Explorar el Código

Merge branch 'tys' into hurx

# Conflicts:
#	ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
hurx hace 1 mes
padre
commit
68ccec9577

+ 10 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java

@@ -22,6 +22,7 @@ import org.dromara.customer.domain.bo.CustomerListBo;
 import org.dromara.customer.domain.bo.CustomerSalesInfoBo;
 import org.dromara.customer.domain.bo.MessagePublishCustomerBo;
 import org.dromara.customer.domain.dto.SetCustomerInfoTagDto;
+import org.dromara.customer.domain.dto.ReleaseToPoolDto;
 import org.dromara.customer.domain.vo.*;
 import org.dromara.customer.listener.CustomerImportListener;
 import org.dromara.customer.service.ICustomerInfoService;
@@ -239,6 +240,15 @@ public class CustomerInfoController extends BaseController {
         return toAjax(customerInfoService.claimPool(bo));
     }
 
+    /**
+     * 退回客户到公海
+     */
+    @Log(title = "客户信息", businessType = BusinessType.UPDATE)
+    @PostMapping("/releaseToPool")
+    public R<Integer> releaseToPool(@RequestBody ReleaseToPoolDto bo) {
+        return R.ok(customerInfoService.releaseToPool(bo.getCustomerIds(), bo.getReason()));
+    }
+
     /**
      * 导入数据
      *

+ 5 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerClaimBo.java

@@ -37,4 +37,9 @@ public class CustomerClaimBo implements Serializable {
      * 是否保留已有负责人 (0: 否, 1: 是)
      */
     private String keepOldManager;
+
+    /**
+     * 部门ID
+     */
+    private Long deptId;
 }

+ 22 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/dto/ReleaseToPoolDto.java

@@ -0,0 +1,22 @@
+package org.dromara.customer.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 退回到公海 DTO
+ */
+@Data
+public class ReleaseToPoolDto implements Serializable {
+    /**
+     * 客户ID列表
+     */
+    private List<Long> customerIds;
+
+    /**
+     * 退回原因
+     */
+    private String reason;
+}

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerInfoService.java

@@ -126,6 +126,15 @@ public interface ICustomerInfoService extends IService<CustomerInfo> {
      */
     Boolean claimPool(CustomerClaimBo claimBo);
 
+    /**
+     * 退回客户到公海
+     *
+     * @param customerIds 客户ID列表
+     * @param reason 退回原因
+     * @return 更新数量
+     */
+    int releaseToPool(List<Long> customerIds, String reason);
+
 
     Map<Long, String> selectCustomerNameByIds(Set<Long> ids);
 

+ 42 - 22
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java

@@ -552,13 +552,16 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
             Set<Long> deptIds = new HashSet<>();
 
             records.forEach(vo -> {
-                if (vo.getSalesPersonId() != null) staffIds.add(vo.getSalesPersonId());
-                if (vo.getServiceStaffId() != null) staffIds.add(vo.getServiceStaffId());
-                if (vo.getCreditLevelId() != null) creditLevelIds.add(vo.getCreditLevelId());
+                // 如果是公海客户,不处理销售ERP相关内容(负责人、客服、部门、信用等级)
+                if (!"true".equals(bo.getIsHighSeas())) {
+                    if (vo.getSalesPersonId() != null) staffIds.add(vo.getSalesPersonId());
+                    if (vo.getServiceStaffId() != null) staffIds.add(vo.getServiceStaffId());
+                    if (vo.getBelongingDepartmentId() != null) deptIds.add(vo.getBelongingDepartmentId());
+                    if (vo.getCreditLevelId() != null) creditLevelIds.add(vo.getCreditLevelId());
+                }
                 if (vo.getBelongCompanyId() != null) companyIds.add(vo.getBelongCompanyId());
                 if (vo.getEnterpriseTypeId() != null) enterpriseTypeIds.add(vo.getEnterpriseTypeId());
                 if (vo.getCustomerLevelId() != null) customerLevelIds.add(vo.getCustomerLevelId());
-                if (vo.getBelongingDepartmentId() != null) deptIds.add(vo.getBelongingDepartmentId());
             });
 
             // 1. 批量查询业务员和客服名称 (远程调用)
@@ -596,13 +599,19 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
 
             // 8. 填充数据
             records.forEach(vo -> {
-                vo.setSalesPersonName(staffMap.get(vo.getSalesPersonId()));
-                vo.setServiceStaffName(staffMap.get(vo.getServiceStaffId()));
+                if (StringUtils.isBlank(vo.getSalesPersonName())) {
+                    vo.setSalesPersonName(staffMap.get(vo.getSalesPersonId()));
+                }
+                if (StringUtils.isBlank(vo.getServiceStaffName())) {
+                    vo.setServiceStaffName(staffMap.get(vo.getServiceStaffId()));
+                }
                 vo.setCreditLevelName(creditLevelMap.get(vo.getCreditLevelId()));
                 vo.setCompanyName(companyMap.get(vo.getBelongCompanyId()));
                 vo.setEnterpriseTypeName(enterpriseTypeMap.get(vo.getEnterpriseTypeId()));
                 vo.setCustomerLevelName(customerLevelMap.get(vo.getCustomerLevelId()));
-                vo.setDeptName(deptMap.get(vo.getBelongingDepartmentId()));
+                if (StringUtils.isBlank(vo.getDeptName())) {
+                    vo.setDeptName(deptMap.get(vo.getBelongingDepartmentId()));
+                }
                 vo.setCooperationName(cooperationMap.get(vo.getStatus()));
             });
         }
@@ -1338,8 +1347,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
     @Override
     @Transactional(rollbackFor = Exception.class)
     public int transferSalesPerson(List<Long> customerIds, Long salesPersonId, Long deptId) {
-        if (CollUtil.isEmpty(customerIds)) {
-            log.warn("转移业务人员失败,客户 ID 列表为空");
+        if (CollUtil.isEmpty(customerIds) || salesPersonId == null) {
             return 0;
         }
 
@@ -1438,6 +1446,12 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 customerIds, serviceStaffId, e.getMessage(), e);
             throw new ServiceException("转移客服人员失败:" + e.getMessage());
         }
+
+        // 直接进行批量更新
+        return baseMapper.update(null, new LambdaUpdateWrapper<CustomerInfo>()
+            .set(CustomerInfo::getServiceStaffId, serviceStaffId)
+            .in(CustomerInfo::getId, customerIds)
+        );
     }
 
     /**
@@ -1504,27 +1518,33 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
     @Transactional(rollbackFor = Exception.class)
     public Boolean claimPool(CustomerClaimBo claimBo) {
         Long customerId = claimBo.getId();
-        CustomerSalesInfo salesInfo = customerSalesInfoMapper.selectOne(new LambdaQueryWrapper<CustomerSalesInfo>()
-            .eq(CustomerSalesInfo::getCustomerId, customerId));
-
-        if (salesInfo == null) {
-            salesInfo = new CustomerSalesInfo();
-            salesInfo.setCustomerId(customerId);
-            salesInfo.setSalesPersonId(claimBo.getSalesPersonId());
-            salesInfo.setServiceStaffId(claimBo.getServiceStaffId());
-            salesInfo.setStatus("0");
-            return customerSalesInfoMapper.insert(salesInfo) > 0;
-        }
-
-        // 更新销售负责人和客服
+        // 认领操作仅更新客户主表,不再涉及到销售信息表
         CustomerInfo customer = new CustomerInfo();
         customer.setId(customerId);
         customer.setSalesPersonId(claimBo.getSalesPersonId());
         customer.setServiceStaffId(claimBo.getServiceStaffId());
+        customer.setBelongingDepartmentId(claimBo.getDeptId());
         customer.setStatus("0"); // 认领成功后,将客户主表状态改为有效
         return baseMapper.updateById(customer) > 0;
     }
 
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public int releaseToPool(List<Long> customerIds, String reason) {
+        if (customerIds == null || customerIds.isEmpty()) {
+            return 0;
+        }
+
+        // 使用 LambdaUpdateWrapper 显式更新字段为 null,因为 updateById 默认忽略 null 值
+        return baseMapper.update(null, new LambdaUpdateWrapper<CustomerInfo>()
+            .set(CustomerInfo::getSalesPersonId, null)
+            .set(CustomerInfo::getServiceStaffId, null)
+            .set(CustomerInfo::getBelongingDepartmentId, null)
+            .set(CustomerInfo::getStatus, "1") // 标记为公海状态
+            .in(CustomerInfo::getId, customerIds)
+        );
+    }
+
     @Override
     public CustomerInfoVo selectCustomerByName(String customerName) {
         return baseMapper.selectVoOne(new LambdaQueryWrapper<CustomerInfo>().eq(CustomerInfo::getCustomerName, customerName));

+ 10 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SalesAnnualFinalizationServiceImpl.java

@@ -15,8 +15,10 @@ import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.redis.utils.SequenceUtils;
 import org.dromara.customer.domain.SalesAnnualFinalization;
 import org.dromara.customer.domain.bo.SalesAnnualFinalizationBo;
+import org.dromara.customer.domain.vo.CustomerInfoVo;
 import org.dromara.customer.domain.vo.SalesAnnualFinalizationVo;
 import org.dromara.customer.mapper.SalesAnnualFinalizationMapper;
+import org.dromara.customer.service.ICustomerInfoService;
 import org.dromara.customer.service.IOperationLogService;
 import org.dromara.customer.domain.bo.TeamMemberBo;
 import org.dromara.customer.service.ITeamMemberService;
@@ -48,6 +50,7 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
     private final SalesAnnualFinalizationMapper baseMapper;
     private final IOperationLogService operationLogService;
     private final ITeamMemberService teamMemberService;
+    private final ICustomerInfoService customerInfoService;
 
     @DubboReference
     private RemoteUserService remoteUserService;
@@ -106,6 +109,13 @@ public class SalesAnnualFinalizationServiceImpl implements ISalesAnnualFinalizat
             add.setProjectNo(SequenceUtils.nextPaddedIdStr(PROJECT_NO_KEY, Duration.ofDays(3650), 6));
         }
 
+        if (StrUtil.isBlank(add.getCustomNo()) && StrUtil.isNotBlank(add.getCustomName())) {
+            CustomerInfoVo customerInfo = customerInfoService.selectCustomerByName(add.getCustomName());
+            if (customerInfo != null && StrUtil.isNotBlank(customerInfo.getCustomerNo())) {
+                add.setCustomNo(customerInfo.getCustomerNo());
+            }
+        }
+
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setId(add.getId());

+ 6 - 0
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerInfoMapper.xml

@@ -62,15 +62,21 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             csi.credit_management_id AS creditLevelId,
             csi.accounts_receivable AS accountsReceivable,
             ci.sales_person_id AS salesPersonId,
+            sp.staff_name AS salesPersonName,
             ci.belong_company_id AS belongCompanyId,
             ci.customer_type_id AS enterpriseTypeId,
             ci.customer_level_id AS customerLevelId,
             ci.service_staff_id AS serviceStaffId,
+            ss.staff_name AS serviceStaffName,
             ci.belonging_department_id AS belongingDepartmentId,
+            sd.dept_name AS deptName,
             ci.status
         FROM customer_info ci
         LEFT JOIN customer_sales_info csi ON ci.id = csi.customer_id AND csi.del_flag = '0'
         LEFT JOIN industry_category ic ON ci.industry_category_id = ic.id AND ic.del_flag = '0'
+        LEFT JOIN com_staff sp ON ci.sales_person_id = sp.staff_id AND sp.del_flag = '0'
+        LEFT JOIN com_staff ss ON ci.service_staff_id = ss.staff_id AND ss.del_flag = '0'
+        LEFT JOIN sys_dept sd ON sp.dept_id = sd.dept_id
         <where>
             ci.del_flag = '0'
             <choose>

+ 49 - 0
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SalesAnnualFinalizationMapper.xml

@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.customer.mapper.SalesAnnualFinalizationMapper">
+
+    <select id="selectSalesAnnualFinalizationList" resultType="org.dromara.customer.domain.vo.SalesAnnualFinalizationVo">
+        SELECT s.*, d.dept_name AS deptName
+        FROM salesannualfinalization s
+        LEFT JOIN com_staff cs ON s.Leader = cs.staff_id
+        LEFT JOIN sys_dept d ON cs.dept_id = d.dept_id
+        <where>
+            s.IsDelete = 0
+            <if test="bo.projectName != null and bo.projectName != ''">
+                AND s.ProjectName LIKE concat('%', #{bo.projectName}, '%')
+            </if>
+            <if test="bo.companyNo != null and bo.companyNo != ''">
+                AND s.CompanyNo = #{bo.companyNo}
+            </if>
+            <if test="bo.customName != null and bo.customName != ''">
+                AND s.CustomName LIKE concat('%', #{bo.customName}, '%')
+            </if>
+            <if test="bo.leader != null">
+                AND s.Leader = #{bo.leader}
+            </if>
+            <if test="bo.deptNo != null and bo.deptNo != ''">
+                AND (s.DeptNo = #{bo.deptNo} OR cs.dept_id = #{bo.deptNo})
+            </if>
+            <if test="bo.projectStatus != null">
+                AND s.ProjectStatus = #{bo.projectStatus}
+            </if>
+            <if test="bo.projectLevel != null">
+                AND s.ProjectLevel = #{bo.projectLevel}
+            </if>
+            <if test="bo.businessType != null">
+                AND s.BusinessType = #{bo.businessType}
+            </if>
+            <if test="bo.finalizationType != null">
+                AND s.FinalizationType = #{bo.finalizationType}
+            </if>
+            <if test="bo.productSupport != null and bo.productSupport != ''">
+                AND s.ProductSupport = #{bo.productSupport}
+            </if>
+            ${bo.params.dataScope}
+        </where>
+        ORDER BY s.create_time DESC
+    </select>
+
+</mapper>