| | |
| | | import com.baomidou.mybatisplus.core.toolkit.Wrappers; |
| | | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; |
| | | import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; |
| | | import com.ruoyi.basic.dto.CustomerContactDto; |
| | | import com.ruoyi.basic.dto.CustomerDto; |
| | | import com.ruoyi.basic.dto.CustomerFollowUpDto; |
| | | import com.ruoyi.basic.mapper.CustomerContactMapper; |
| | | import com.ruoyi.basic.mapper.CustomerMapper; |
| | | import com.ruoyi.basic.pojo.*; |
| | | import com.ruoyi.basic.service.CustomerFollowUpFileService; |
| | | import com.ruoyi.basic.service.CustomerFollowUpService; |
| | | import com.ruoyi.basic.service.CustomerReturnVisitService; |
| | | import com.ruoyi.basic.service.CustomerUserService; |
| | | import com.ruoyi.basic.service.ICustomerService; |
| | | import com.ruoyi.basic.service.*; |
| | | import com.ruoyi.basic.vo.CustomerVo; |
| | | import com.ruoyi.common.utils.SecurityUtils; |
| | | import com.ruoyi.common.utils.StringUtils; |
| | | import com.ruoyi.common.utils.poi.ExcelUtil; |
| | | import com.ruoyi.framework.security.LoginUser; |
| | | import com.ruoyi.framework.web.domain.AjaxResult; |
| | | import com.ruoyi.framework.web.domain.R; |
| | | import com.ruoyi.sales.mapper.SalesLedgerMapper; |
| | | import com.ruoyi.sales.pojo.SalesLedger; |
| | | import lombok.AllArgsConstructor; |
| | |
| | | private CustomerReturnVisitService customerReturnVisitService; |
| | | @Autowired |
| | | private CustomerUserService customerUserService; |
| | | @Autowired |
| | | private CustomerContactMapper customerContactMapper; |
| | | |
| | | /** |
| | | * 查询客户档案 |
| | |
| | | }).collect(Collectors.toList()); |
| | | |
| | | customerVo.setFollowUpList(followUpDtoList); |
| | | } |
| | | //查询联系人信息 |
| | | List<CustomerContact> customerContactList = customerContactMapper.selectList( |
| | | new QueryWrapper<CustomerContact>().lambda() |
| | | .apply("FIND_IN_SET({0}, customer_id)", id) |
| | | ); |
| | | if (!CollectionUtils.isEmpty(customerContactList)) { |
| | | List<CustomerContactDto> contactDtoList = customerContactList.stream().map(contact -> { |
| | | CustomerContactDto contactDto = new CustomerContactDto(); |
| | | BeanUtils.copyProperties(contact, contactDto); |
| | | return contactDto; |
| | | }).collect(Collectors.toList()); |
| | | customerVo.setContactList(contactDtoList); |
| | | } |
| | | |
| | | return customerVo; |
| | |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int insertCustomer(Customer customer) { |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int insertCustomer(CustomerDto customer) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long tenantId = loginUser.getTenantId(); |
| | | customer.setTenantId(tenantId); |
| | | return customerMapper.insert(customer); |
| | | customerMapper.insert(customer); |
| | | syncCustomerContacts(customer.getId(), customer.getContactList()); |
| | | return 1; |
| | | } |
| | | |
| | | /** |
| | |
| | | * @return 结果 |
| | | */ |
| | | @Override |
| | | public int updateCustomer(Customer customer) { |
| | | @Transactional(rollbackFor = Exception.class) |
| | | public int updateCustomer(CustomerDto customer) { |
| | | LoginUser loginUser = SecurityUtils.getLoginUser(); |
| | | Long tenantId = loginUser.getTenantId(); |
| | | customer.setTenantId(tenantId); |
| | | return customerMapper.updateById(customer); |
| | | int rows = customerMapper.updateById(customer); |
| | | syncCustomerContacts(customer.getId(), customer.getContactList()); |
| | | return rows; |
| | | } |
| | | |
| | | private void syncCustomerContacts(Long customerId, List<? extends CustomerContact> contactList) { |
| | | List<CustomerContact> allContacts = customerContactMapper.selectList(new QueryWrapper<>()); |
| | | Map<String, CustomerContact> submittedContactMap = new LinkedHashMap<>(); |
| | | if (!CollectionUtils.isEmpty(contactList)) { |
| | | for (CustomerContact contact : contactList) { |
| | | if (contact == null) { |
| | | continue; |
| | | } |
| | | submittedContactMap.putIfAbsent(buildContactKey(contact), contact); |
| | | } |
| | | } |
| | | |
| | | // 先同步本次提交的联系人,按“姓名 + 手机号”聚合客户ID。 |
| | | for (CustomerContact contact : submittedContactMap.values()) { |
| | | contact.setCustomerId(buildContactCustomerIds(allContacts, contact, customerId)); |
| | | if (contact.getId() == null) { |
| | | customerContactMapper.insert(contact); |
| | | allContacts.add(contact); |
| | | } else { |
| | | customerContactMapper.updateById(contact); |
| | | replaceLocalContact(allContacts, contact); |
| | | } |
| | | } |
| | | |
| | | Set<String> submittedContactKeys = submittedContactMap.keySet(); |
| | | // 再处理本次已删除的联系人,把当前客户从历史关联里移除。 |
| | | for (CustomerContact existingContact : new ArrayList<>(allContacts)) { |
| | | if (!containsCustomerId(existingContact.getCustomerId(), customerId)) { |
| | | continue; |
| | | } |
| | | if (submittedContactKeys.contains(buildContactKey(existingContact))) { |
| | | continue; |
| | | } |
| | | String updatedCustomerIds = removeCustomerId(existingContact.getCustomerId(), customerId); |
| | | if (StringUtils.isEmpty(updatedCustomerIds)) { |
| | | // 没有剩余客户关联时,直接删除联系人记录。 |
| | | customerContactMapper.deleteById(existingContact.getId()); |
| | | } else { |
| | | existingContact.setCustomerId(updatedCustomerIds); |
| | | customerContactMapper.updateById(existingContact); |
| | | } |
| | | } |
| | | } |
| | | |
| | | // 按联系人姓名和手机号汇总历史客户ID,并追加当前客户ID。 |
| | | private String buildContactCustomerIds(List<CustomerContact> customerContacts, CustomerContact contact, Long customerId) { |
| | | LinkedHashSet<String> customerIdSet = new LinkedHashSet<>(); |
| | | if (!CollectionUtils.isEmpty(customerContacts)) { |
| | | customerContacts.stream() |
| | | .filter(Objects::nonNull) |
| | | .filter(item -> Objects.equals(item.getContactPerson(), contact.getContactPerson()) |
| | | && Objects.equals(item.getContactPhone(), contact.getContactPhone())) |
| | | .map(CustomerContact::getCustomerId) |
| | | .filter(StringUtils::isNotEmpty) |
| | | .forEach(ids -> Arrays.stream(ids.split(",")) |
| | | .map(String::trim) |
| | | .filter(StringUtils::isNotEmpty) |
| | | .forEach(customerIdSet::add)); |
| | | } |
| | | customerIdSet.add(String.valueOf(customerId)); |
| | | return String.join(",", customerIdSet); |
| | | } |
| | | |
| | | // 判断联系人关联列表里是否包含当前客户ID。 |
| | | private boolean containsCustomerId(String customerIds, Long customerId) { |
| | | if (StringUtils.isEmpty(customerIds) || customerId == null) { |
| | | return false; |
| | | } |
| | | String currentCustomerId = String.valueOf(customerId); |
| | | return Arrays.stream(customerIds.split(",")) |
| | | .map(String::trim) |
| | | .anyMatch(currentCustomerId::equals); |
| | | } |
| | | |
| | | // 从联系人关联列表里移除当前客户ID,并保持逗号拼接格式。 |
| | | private String removeCustomerId(String customerIds, Long customerId) { |
| | | if (StringUtils.isEmpty(customerIds) || customerId == null) { |
| | | return customerIds; |
| | | } |
| | | String currentCustomerId = String.valueOf(customerId); |
| | | return Arrays.stream(customerIds.split(",")) |
| | | .map(String::trim) |
| | | .filter(StringUtils::isNotEmpty) |
| | | .filter(id -> !currentCustomerId.equals(id)) |
| | | .distinct() |
| | | .collect(Collectors.joining(",")); |
| | | } |
| | | |
| | | // 生成联系人业务唯一键,用于对本次提交数据去重比对。 |
| | | private String buildContactKey(CustomerContact contact) { |
| | | return StringUtils.defaultString(contact.getContactPerson()) + "_" + StringUtils.defaultString(contact.getContactPhone()); |
| | | } |
| | | |
| | | // 更新内存中的联系人快照,避免后续增删判断使用旧数据。 |
| | | private void replaceLocalContact(List<CustomerContact> customerContacts, CustomerContact targetContact) { |
| | | for (int i = 0; i < customerContacts.size(); i++) { |
| | | CustomerContact customerContact = customerContacts.get(i); |
| | | if (Objects.equals(customerContact.getId(), targetContact.getId())) { |
| | | customerContacts.set(i, targetContact); |
| | | return; |
| | | } |
| | | } |
| | | } |
| | | |
| | | /** |
| | |
| | | .eq(CustomerUser::getCustomerId, id) |
| | | ); |
| | | } |
| | | // 删除客户对应的联系人关联 |
| | | removeCustomerContactsByCustomerIds(idList); |
| | | |
| | | // 删除客户主表数据 |
| | | return customerMapper.deleteBatchIds(idList); |
| | | } |
| | | |
| | | private void removeCustomerContactsByCustomerIds(List<Long> customerIds) { |
| | | if (CollectionUtils.isEmpty(customerIds)) { |
| | | return; |
| | | } |
| | | List<CustomerContact> customerContacts = customerContactMapper.selectList(new QueryWrapper<>()); |
| | | if (CollectionUtils.isEmpty(customerContacts)) { |
| | | return; |
| | | } |
| | | Set<Long> customerIdSet = customerIds.stream() |
| | | .filter(Objects::nonNull) |
| | | .collect(Collectors.toSet()); |
| | | for (CustomerContact customerContact : customerContacts) { |
| | | String contactCustomerIds = customerContact.getCustomerId(); |
| | | if (StringUtils.isEmpty(contactCustomerIds)) { |
| | | continue; |
| | | } |
| | | String updatedCustomerIds = Arrays.stream(contactCustomerIds.split(",")) |
| | | .map(String::trim) |
| | | .filter(StringUtils::isNotEmpty) |
| | | .filter(id -> { |
| | | Long parsedId = parseCustomerId(id); |
| | | return parsedId == null || !customerIdSet.contains(parsedId); |
| | | }) |
| | | .distinct() |
| | | .collect(Collectors.joining(",")); |
| | | if (StringUtils.isEmpty(updatedCustomerIds)) { |
| | | customerContactMapper.deleteById(customerContact.getId()); |
| | | } else if (!updatedCustomerIds.equals(contactCustomerIds)) { |
| | | customerContact.setCustomerId(updatedCustomerIds); |
| | | customerContactMapper.updateById(customerContact); |
| | | } |
| | | } |
| | | } |
| | | |
| | | private Long parseCustomerId(String customerId) { |
| | | try { |
| | | return Long.valueOf(customerId); |
| | | } catch (NumberFormatException e) { |
| | | return null; |
| | | } |
| | | } |
| | | |
| | | @Override |
| | |
| | | } |
| | | |
| | | @Override |
| | | public AjaxResult importData(MultipartFile file, Integer type) { |
| | | public R importData(MultipartFile file, Integer type) { |
| | | try { |
| | | ExcelUtil<Customer> util = new ExcelUtil<Customer>(Customer.class); |
| | | List<Customer> userList = util.importExcel(file.getInputStream()); |
| | | if (CollectionUtils.isEmpty(userList)) { |
| | | return AjaxResult.warn("模板错误或导入数据为空"); |
| | | return R.fail("模板错误或导入数据为空"); |
| | | } |
| | | |
| | | // 根据 type 参数设置客户类型(私海/公海) |
| | |
| | | }); |
| | | } |
| | | this.saveOrUpdateBatch(userList); |
| | | return AjaxResult.success(true); |
| | | return R.ok(true); |
| | | } catch (Exception e) { |
| | | e.printStackTrace(); |
| | | return AjaxResult.error("导入失败"); |
| | | return R.fail("导入失败"); |
| | | } |
| | | |
| | | } |
| | |
| | | @Override |
| | | public void assignCustomer(CustomerDto customerDto) { |
| | | Customer customer = customerMapper.selectById(customerDto.getId()); |
| | | if (customer.getType() == 1 && customer.getIsAssigned() == 0) { // 公海且可分配 |
| | | if (customer.getType() == 1 ) { // 公海且可分配 |
| | | customer.setIsAssigned(1); |
| | | customer.setUsageStatus(1L); |
| | | customer.setUsageUser(customerDto.getUsageUser()); |
| | |
| | | customer.setUsageStatus(0L); |
| | | customer.setUsageUser(0L); |
| | | customerMapper.updateById(customer); |
| | | |
| | | |
| | | // 删除该客户的所有共享关系 |
| | | customerUserService.remove( |
| | | new QueryWrapper<CustomerUser>().lambda() |
| | |
| | | customerUserService.saveBatch(customerUsers); |
| | | } |
| | | |
| | | @Override |
| | | public Boolean back(Long id) { |
| | | //将客户的type改为1 且直接分配给当前用户 |
| | | Customer customer = customerMapper.selectById(id); |
| | | customer.setType(1); |
| | | customer.setIsAssigned(0); |
| | | return this.updateById(customer); |
| | | } |
| | | |
| | | /** |
| | | * 下划线命名转驼峰命名 |
| | | */ |
| | |
| | | } |
| | | return sb.toString(); |
| | | } |
| | | } |
| | | } |