From 544bfa4c9c8b5777d1440b93e12a5e51ae916156 Mon Sep 17 00:00:00 2001
From: liyong <18434998025@163.com>
Date: 星期五, 17 四月 2026 15:36:07 +0800
Subject: [PATCH] feat(basic): 客户管理模块重构及数据库配置更新

---
 src/main/java/com/ruoyi/basic/controller/CustomerPrivatePoolController.java    |   93 ++++
 src/main/java/com/ruoyi/basic/pojo/Customer.java                               |    6 
 src/main/resources/mapper/basic/CustomerMapper.xml                             |   33 +
 src/main/java/com/ruoyi/basic/pojo/CustomerPrivate.java                        |  115 +++++
 src/main/java/com/ruoyi/basic/service/CustomerPrivatePoolService.java          |   39 +
 src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java    |    2 
 src/main/resources/mapper/basic/CustomerPrivatePoolMapper.xml                  |   97 ++++
 src/main/java/com/ruoyi/basic/mapper/CustomerPrivatePoolMapper.java            |   29 +
 src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java            |  147 ++---
 src/main/java/com/ruoyi/basic/pojo/CustomerPrivatePool.java                    |   68 ++
 src/main/resources/mapper/sales/InvoiceLedgerMapper.xml                        |    2 
 src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java         |    7 
 src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java |    6 
 src/main/java/com/ruoyi/basic/dto/CustomerPrivateDto.java                      |   12 
 src/main/java/com/ruoyi/basic/service/CustomerPrivateService.java              |   33 +
 src/main/java/com/ruoyi/basic/service/impl/CustomerPrivateServiceImpl.java     |  112 ++++
 src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java                       |    8 
 src/main/java/com/ruoyi/CodeGenerator.java                                     |    6 
 src/main/resources/mapper/basic/CustomerPrivateMapper.xml                      |   25 +
 src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java                |    2 
 src/main/java/com/ruoyi/basic/service/ICustomerService.java                    |    6 
 src/main/java/com/ruoyi/basic/controller/CustomerPrivateController.java        |   90 +++
 src/main/java/com/ruoyi/basic/dto/CustomerPrivatePoolDto.java                  |  124 +++++
 src/main/java/com/ruoyi/basic/mapper/CustomerPrivateMapper.java                |   18 
 src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java                   |    4 
 src/main/java/com/ruoyi/basic/service/impl/CustomerPrivatePoolServiceImpl.java |  234 ++++++++++
 src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java       |    2 
 src/main/java/com/ruoyi/basic/dto/CustomerDto.java                             |    4 
 src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java                       |    6 
 src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java                    |    2 
 src/main/java/com/ruoyi/basic/controller/CustomerController.java               |    9 
 31 files changed, 1,231 insertions(+), 110 deletions(-)

diff --git a/src/main/java/com/ruoyi/CodeGenerator.java b/src/main/java/com/ruoyi/CodeGenerator.java
index 6356273..f3e305e 100644
--- a/src/main/java/com/ruoyi/CodeGenerator.java
+++ b/src/main/java/com/ruoyi/CodeGenerator.java
@@ -19,11 +19,11 @@
 // 婕旂ず渚嬪瓙锛屾墽琛� main 鏂规硶鎺у埗鍙拌緭鍏ユā鍧楄〃鍚嶅洖杞﹁嚜鍔ㄧ敓鎴愬搴旈」鐩洰褰曚腑
 public class CodeGenerator {
 
-    public static String database_url = "jdbc:mysql://1.15.17.182:9999/product-inventory-management-new";
+    public static String database_url = "jdbc:mysql://localhost:3300/product-inventory-management-new";
     public static String database_username = "root";
-    public static String database_password= "xd@123456..";
+    public static String database_password= "root";
     public static String author = "鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃";
-    public static String model = "staff"; // 妯″潡
+    public static String model = "basic"; // 妯″潡
     public static String setParent = "com.ruoyi."+ model; // 鍖呰矾寰�
     public static String tablePrefix = ""; // 璁剧疆杩囨护琛ㄥ墠缂�
     public static void main(String[] args) {
diff --git a/src/main/java/com/ruoyi/basic/controller/CustomerController.java b/src/main/java/com/ruoyi/basic/controller/CustomerController.java
index 94c4007..7e931da 100644
--- a/src/main/java/com/ruoyi/basic/controller/CustomerController.java
+++ b/src/main/java/com/ruoyi/basic/controller/CustomerController.java
@@ -2,6 +2,7 @@
 
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerDto;
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.basic.service.ICustomerService;
 import com.ruoyi.common.utils.poi.ExcelUtil;
@@ -9,6 +10,7 @@
 import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
 import com.ruoyi.framework.web.controller.BaseController;
 import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.web.domain.R;
 import lombok.AllArgsConstructor;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.web.multipart.MultipartFile;
@@ -32,8 +34,9 @@
      * 鏌ヨ瀹㈡埛妗f鍒楄〃
      */
     @GetMapping("/list")
-    public IPage<Customer> list(Page<Customer> page, Customer customer) {
-        return customerService.selectCustomerList(page, customer);
+    public R list(Page<CustomerDto> page, CustomerDto customer) {
+        IPage<CustomerDto> customerDtoIPage = customerService.selectCustomerList(page, customer);
+        return R.ok(customerDtoIPage);
     }
 
     /**
@@ -116,4 +119,6 @@
     public List customerList(Customer customer) {
         return customerService.customerList(customer);
     }
+
+
 }
diff --git a/src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java b/src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java
index 2b70438..d10e370 100644
--- a/src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java
+++ b/src/main/java/com/ruoyi/basic/controller/CustomerFollowUpController.java
@@ -46,7 +46,7 @@
     @ApiOperation("鏌ヨ瀹㈡埛璺熻繘鍒楄〃")
     public IPage<CustomerFollowUp> list(Page<CustomerFollowUp> page, CustomerFollowUp customerFollowUp) {
         LambdaQueryWrapper<CustomerFollowUp> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(customerFollowUp.getCustomerId() != null, CustomerFollowUp::getCustomerId, customerFollowUp.getCustomerId())
+        queryWrapper.eq(customerFollowUp.getCustomerPrivatePoolId() != null, CustomerFollowUp::getCustomerPrivatePoolId, customerFollowUp.getCustomerPrivatePoolId())
                 .like(customerFollowUp.getFollowerUserName() != null, CustomerFollowUp::getFollowerUserName, customerFollowUp.getFollowerUserName())
                 .orderByDesc(CustomerFollowUp::getFollowUpTime);
         return customerFollowUpService.page(page, queryWrapper);
diff --git a/src/main/java/com/ruoyi/basic/controller/CustomerPrivateController.java b/src/main/java/com/ruoyi/basic/controller/CustomerPrivateController.java
new file mode 100644
index 0000000..1807ce7
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/controller/CustomerPrivateController.java
@@ -0,0 +1,90 @@
+package com.ruoyi.basic.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerDto;
+import com.ruoyi.basic.dto.CustomerPrivateDto;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.CustomerPrivate;
+import com.ruoyi.basic.service.CustomerPrivatePoolService;
+import com.ruoyi.basic.service.CustomerPrivateService;
+import com.ruoyi.basic.service.ICustomerService;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.web.domain.R;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.web.multipart.MultipartFile;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+import static com.ruoyi.framework.web.domain.AjaxResult.success;
+
+/**
+ * <p>
+ * 瀹㈡埛妗f 鍓嶇鎺у埗鍣�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-17 10:39:09
+ */
+@RestController
+@RequestMapping("/customerPrivate")
+public class CustomerPrivateController {
+    @Autowired
+    private CustomerPrivateService customerPrivateService;
+
+    @Autowired
+    private CustomerPrivatePoolService customerPrivatePoolService;
+
+
+    @PostMapping("/add")
+    public R add(@RequestBody CustomerPrivateDto customerPrivateDto) {
+        return R.ok(customerPrivateService.add(customerPrivateDto));
+    }
+
+
+    @DeleteMapping("/delete")
+    public R delete(@RequestBody List<Long> ids) {
+        return R.ok(customerPrivateService.delete(ids));
+    }
+
+
+    /**
+     * 瀵煎叆瀹㈡埛妗f
+     */
+    @Log(title = "瀹㈡埛妗f", businessType = BusinessType.IMPORT)
+    @PostMapping("/importData")
+    public R importData(MultipartFile file) throws Exception {
+
+        return customerPrivateService.importData(file);
+    }
+
+    /**
+     * 瀵煎嚭瀹㈡埛妗f鍒楄〃
+     */
+    @Log(title = "瀹㈡埛妗f", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(HttpServletResponse response, CustomerPrivatePoolDto customerPrivatePoolDto) {
+        List<Long> ids = customerPrivatePoolDto.getIds();
+        List<CustomerPrivatePoolDto> list;
+        if (ids != null && ids.size() > 0) {
+            list = customerPrivatePoolService.selectCustomerPrivatePoolDtoListByIds(ids);
+        } else {
+            list = customerPrivatePoolService.selectCustomerPrivatePoolDtoLists(customerPrivatePoolDto);
+        }
+        ExcelUtil<CustomerPrivatePoolDto> util = new ExcelUtil<CustomerPrivatePoolDto>(CustomerPrivatePoolDto.class);
+        util.exportExcel(response, list, "瀹㈡埛妗f鏁版嵁");
+    }
+
+    @PostMapping("/downloadTemplate")
+    @Log(title = "瀹㈡埛妗f-涓嬭浇妯℃澘", businessType = BusinessType.EXPORT)
+    public void downloadTemplate(HttpServletResponse response) {
+        ExcelUtil<CustomerPrivatePoolDto> util = new ExcelUtil<CustomerPrivatePoolDto>(CustomerPrivatePoolDto.class);
+        util.importTemplateExcel(response, "瀹㈡埛妗f妯℃澘");
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/controller/CustomerPrivatePoolController.java b/src/main/java/com/ruoyi/basic/controller/CustomerPrivatePoolController.java
new file mode 100644
index 0000000..8b8edf7
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/controller/CustomerPrivatePoolController.java
@@ -0,0 +1,93 @@
+package com.ruoyi.basic.controller;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.CustomerPrivatePool;
+import com.ruoyi.basic.service.CustomerPrivatePoolService;
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.poi.ExcelUtil;
+import com.ruoyi.framework.aspectj.lang.annotation.Log;
+import com.ruoyi.framework.aspectj.lang.enums.BusinessType;
+import com.ruoyi.framework.web.domain.R;
+import io.swagger.annotations.Api;
+import io.swagger.annotations.ApiOperation;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/**
+ * <p>
+ *  鍓嶇鎺у埗鍣� 瀹㈡埛锛堢娴凤級
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-16 04:43:00
+ */
+@RestController
+@Api(tags = "瀹㈡埛锛堢娴凤級")
+@RequestMapping("/customerPrivatePool")
+public class CustomerPrivatePoolController {
+
+    @Autowired
+    private CustomerPrivatePoolService customerPrivatePoolService;
+
+
+    @GetMapping("/listPage")
+    @ApiOperation("瀹㈡埛锛堢娴凤級鍒楄〃")
+    public R listPage(CustomerPrivatePoolDto customerPrivatePoolDto, Page<CustomerPrivatePoolDto> page){
+        //鏌ヨ褰撳墠鐢ㄦ埛鐨勫鎴蜂俊鎭�
+        customerPrivatePoolDto.setBoundId(SecurityUtils.getUserId());
+        IPage<CustomerPrivatePoolDto> listPage = customerPrivatePoolService.listPage(page, customerPrivatePoolDto);
+        return R.ok(listPage);
+    }
+
+    @PostMapping("/add")
+    @ApiOperation("鍒嗛厤瀹㈡埛锛堢娴凤級")
+    public R add(@RequestBody CustomerPrivatePoolDto customerPrivatePool){
+        boolean result = customerPrivatePoolService.add(customerPrivatePool);
+        return R.ok(result);
+    }
+
+    @PutMapping("/update")
+    public R update(@RequestBody CustomerPrivatePoolDto customerPrivatePoolDto) {
+        return R.ok(customerPrivatePoolService.updateCustomerPrivatePoolDto(customerPrivatePoolDto));
+    }
+
+
+    @DeleteMapping("/delete/{id}")
+    @ApiOperation("鍒犻櫎瀹㈡埛锛堢娴凤級")
+    public R delete(@PathVariable Long id){
+        boolean result = customerPrivatePoolService.deleteCustomerPrivatePool(id);
+        return R.ok(result);
+    }
+
+    @PostMapping("/together")
+    @ApiOperation("鍏变韩")
+    public R together( @RequestBody CustomerPrivatePoolDto customerPrivatePool){
+        boolean result = customerPrivatePoolService.together(customerPrivatePool);
+        return R.ok(result);
+    }
+
+    @GetMapping("/info/{id}")
+    @ApiOperation("璇︽儏")
+    public R getInfo(@PathVariable Long id){
+        CustomerPrivatePoolDto customerPrivatePool = customerPrivatePoolService.getInfo(id);
+        return R.ok(customerPrivatePool);
+    }
+
+    @GetMapping("/getbyId/{id}")
+    @ApiOperation("璇︽儏")
+    public R getbyId(@PathVariable Long id){
+        CustomerPrivatePoolDto customerPrivatePool = customerPrivatePoolService.getbyId(id);
+        return R.ok(customerPrivatePool);
+    }
+
+
+
+
+
+}
diff --git a/src/main/java/com/ruoyi/basic/dto/CustomerDto.java b/src/main/java/com/ruoyi/basic/dto/CustomerDto.java
index a8161da..630119f 100644
--- a/src/main/java/com/ruoyi/basic/dto/CustomerDto.java
+++ b/src/main/java/com/ruoyi/basic/dto/CustomerDto.java
@@ -21,4 +21,8 @@
 
     private List<CustomerFollowUpDto> followUpList;
 
+    private String usageUserName;
+
+    private String togetherUserNames;
+
 }
diff --git a/src/main/java/com/ruoyi/basic/dto/CustomerPrivateDto.java b/src/main/java/com/ruoyi/basic/dto/CustomerPrivateDto.java
new file mode 100644
index 0000000..c06ad62
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/dto/CustomerPrivateDto.java
@@ -0,0 +1,12 @@
+package com.ruoyi.basic.dto;
+
+import com.ruoyi.basic.pojo.CustomerPrivate;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class CustomerPrivateDto extends CustomerPrivate {
+
+    private List<CustomerFollowUpDto> followUpList;
+}
diff --git a/src/main/java/com/ruoyi/basic/dto/CustomerPrivatePoolDto.java b/src/main/java/com/ruoyi/basic/dto/CustomerPrivatePoolDto.java
new file mode 100644
index 0000000..c06f542
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/dto/CustomerPrivatePoolDto.java
@@ -0,0 +1,124 @@
+package com.ruoyi.basic.dto;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.basic.pojo.CustomerFollowUp;
+import com.ruoyi.basic.pojo.CustomerPrivatePool;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.util.Date;
+import java.util.List;
+
+@Data
+public class CustomerPrivatePoolDto extends CustomerPrivatePool {
+
+    /**
+     * 瀹㈡埛鍚嶇О
+     */
+    @Excel(name = "瀹㈡埛鍚嶇О")
+    private String customerName;
+    /** 瀹㈡埛鍒嗙被锛氶浂鍞鎴凤紝杩涢攢鍟嗗鎴� */
+
+    @ApiModelProperty(value = "瀹㈡埛瑕乮d")
+    private Long customerId;
+
+    /**
+     * 璺熻繘绋嬪害
+     */
+//    @Excel(name = "璺熻繘绋嬪害")
+    @TableField(exist = false)
+    private String followUpLevel;
+
+    /**
+     * 璺熻繘鏃堕棿
+     */
+//    @Excel(name = "璺熻繘鏃堕棿" , width = 30, dateFormat = "yyyy-MM-dd")
+    @TableField(exist = false)
+    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    private Date followUpTime;
+
+    @Excel(name = "瀹㈡埛鍒嗙被")
+    private String customerType;
+
+
+    private  String addressPhone;
+    /**
+     * 绾崇◣浜鸿瘑鍒彿
+     */
+    @Excel(name = "绾崇◣浜鸿瘑鍒彿")
+    private String taxpayerIdentificationNumber;
+
+    /**
+     * 鍏徃鍦板潃
+     */
+    @Excel(name = "鍏徃鍦板潃")
+    private String companyAddress;
+
+    /**
+     * 鍏徃鐢佃瘽
+     */
+    @Excel(name = "鍏徃鐢佃瘽")
+    private String companyPhone;
+
+    /**
+     * 鑱旂郴浜�
+     */
+    @Excel(name = "鑱旂郴浜�")
+    private String contactPerson;
+
+    /**
+     * 鑱旂郴鐢佃瘽
+     */
+    @Excel(name = "鑱旂郴鐢佃瘽",cellType = Excel.ColumnType.STRING)
+    private String contactPhone;
+
+    /**
+     * 缁存姢浜�
+     */
+    @Excel(name = "缁存姢浜�")
+    private String maintainer;
+
+    /**
+     * 缁存姢鏃堕棿
+     */
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "缁存姢鏃堕棿" , width = 30, dateFormat = "yyyy-MM-dd")
+    private Date maintenanceTime;
+
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty(value = "閾惰鍩烘湰鎴�")
+    @Excel(name = "閾惰鍩烘湰鎴�")
+    private String basicBankAccount;
+
+    @ApiModelProperty(value = "閾惰璐﹀彿")
+    @Excel(name = "閾惰璐﹀彿")
+    private String bankAccount;
+
+    @ApiModelProperty(value = "寮�鎴疯鍙�")
+    @Excel(name = "寮�鎴疯鍙�")
+    private String bankCode;
+    @ApiModelProperty(value = "鍒涘缓鐢ㄦ埛")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+
+    @ApiModelProperty(value = "璺熻繘璁板綍")
+    private List<CustomerFollowUpDto> followUpList;
+
+    @ApiModelProperty(value = "缁戝畾浜篿ds")
+    private List< Long> boundIds;
+
+    @Excel(isExport = false)
+    private List<Long> ids;
+
+
+}
diff --git a/src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java b/src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java
index 1946f26..ac86398 100644
--- a/src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java
+++ b/src/main/java/com/ruoyi/basic/mapper/CustomerMapper.java
@@ -1,7 +1,12 @@
 package com.ruoyi.basic.mapper;
 
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerDto;
 import com.ruoyi.basic.pojo.Customer;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
 
 import java.util.List;
 
@@ -11,6 +16,7 @@
  * @author ruoyi
  * @date 2025-05-07
  */
+@Mapper
 public interface CustomerMapper extends BaseMapper<Customer>
 {
     /**
@@ -60,4 +66,6 @@
      * @return 缁撴灉
      */
     int deleteCustomerByIds(Long[] ids);
+
+    IPage<CustomerDto> listPage(Page<CustomerDto> page, @Param("c") CustomerDto customer);
 }
diff --git a/src/main/java/com/ruoyi/basic/mapper/CustomerPrivateMapper.java b/src/main/java/com/ruoyi/basic/mapper/CustomerPrivateMapper.java
new file mode 100644
index 0000000..4f1bf6d
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/CustomerPrivateMapper.java
@@ -0,0 +1,18 @@
+package com.ruoyi.basic.mapper;
+
+import com.ruoyi.basic.pojo.CustomerPrivate;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+
+/**
+ * <p>
+ * 瀹㈡埛妗f Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-17 10:39:09
+ */
+@Mapper
+public interface CustomerPrivateMapper extends BaseMapper<CustomerPrivate> {
+
+}
diff --git a/src/main/java/com/ruoyi/basic/mapper/CustomerPrivatePoolMapper.java b/src/main/java/com/ruoyi/basic/mapper/CustomerPrivatePoolMapper.java
new file mode 100644
index 0000000..4c6f325
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/mapper/CustomerPrivatePoolMapper.java
@@ -0,0 +1,29 @@
+package com.ruoyi.basic.mapper;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.pojo.CustomerPrivatePool;
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Param;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  Mapper 鎺ュ彛
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-16 04:43:00
+ */
+@Mapper
+public interface CustomerPrivatePoolMapper extends BaseMapper<CustomerPrivatePool> {
+
+    IPage<CustomerPrivatePoolDto> listPage(IPage<CustomerPrivatePoolDto> page, @Param("c") CustomerPrivatePoolDto customerPrivatePoolDto);
+
+    CustomerPrivatePoolDto selectInfo(Long id);
+
+    List<CustomerPrivatePoolDto> selectInfos();
+
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/Customer.java b/src/main/java/com/ruoyi/basic/pojo/Customer.java
index 753d76f..e63c512 100644
--- a/src/main/java/com/ruoyi/basic/pojo/Customer.java
+++ b/src/main/java/com/ruoyi/basic/pojo/Customer.java
@@ -10,6 +10,7 @@
 import io.swagger.annotations.ApiModelProperty;
 import lombok.Data;
 import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import org.checkerframework.checker.units.qual.A;
 
 /**
  * 瀹㈡埛妗f瀵硅薄 customer
@@ -123,4 +124,9 @@
     @TableField(fill = FieldFill.INSERT)
     private Long deptId;
 
+    @ApiModelProperty(value = "浣跨敤鐢ㄦ埛")
+    private Long usageUser;
+    @ApiModelProperty(value = "浣跨敤鐘舵��")
+    private Long usageStatus;
+
 }
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java b/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
index bd73a31..5f174a5 100644
--- a/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
@@ -8,6 +8,7 @@
 import com.baomidou.mybatisplus.annotation.TableName;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
 
 import java.io.Serializable;
 import java.time.LocalDateTime;
@@ -34,9 +35,9 @@
     private Integer id;
 
     /**
-     * 鍏宠仈鐨勫鎴稩D
+     * 鍏宠仈鐨勭娴穒d
      */
-    private Integer customerId;
+    private Long customerPrivatePoolId;
 
     /**
      * 璺熻繘鏂瑰紡
@@ -52,6 +53,7 @@
      * 璺熻繘鏃堕棿
      */
     @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss")
+    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
     private LocalDateTime followUpTime;
 
     /**
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerPrivate.java b/src/main/java/com/ruoyi/basic/pojo/CustomerPrivate.java
new file mode 100644
index 0000000..85f49a5
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerPrivate.java
@@ -0,0 +1,115 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDate;
+import java.util.Date;
+
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 瀹㈡埛妗f
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-17 10:39:09
+ */
+@Getter
+@Setter
+@TableName("customer_private")
+@ApiModel(value = "CustomerPrivate瀵硅薄", description = "瀹㈡埛妗f")
+public class CustomerPrivate implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("瀹㈡埛鍚嶇О")
+    @Excel(name = "瀹㈡埛鍚嶇О")
+    private String customerName;
+
+    @ApiModelProperty("绾崇◣浜鸿瘑鍒彿")
+    @Excel(name = "绾崇◣浜鸿瘑鍒彿")
+    private String taxpayerIdentificationNumber;
+
+    @ApiModelProperty("鍏徃鍦板潃")
+    @Excel(name = "鍏徃鍦板潃")
+    private String companyAddress;
+
+    @ApiModelProperty("鍏徃鐢佃瘽")
+    @Excel(name = "鍏徃鐢佃瘽")
+    private String companyPhone;
+
+    @ApiModelProperty("鑱旂郴浜�")
+    @Excel(name = "鑱旂郴浜�")
+    private String contactPerson;
+
+    @ApiModelProperty("鑱旂郴鐢佃瘽")
+    @Excel(name = "鑱旂郴鐢佃瘽", cellType = Excel.ColumnType.STRING)
+    private String contactPhone;
+
+    @ApiModelProperty("缁存姢浜�")
+    @Excel(name = "缁存姢浜�")
+    private String maintainer;
+
+    @ApiModelProperty("缁存姢鏃堕棿")
+    @JsonFormat(pattern = "yyyy-MM-dd")
+    @Excel(name = "缁存姢鏃堕棿", width = 30, dateFormat = "yyyy-MM-dd")
+    private Date maintenanceTime;
+
+    @ApiModelProperty("绉熸埛ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    @ApiModelProperty("閾惰鍩烘湰鎴�")
+    @Excel(name = "閾惰鍩烘湰鎴�")
+    private String basicBankAccount;
+
+    @ApiModelProperty("閾惰璐﹀彿")
+    @Excel(name = "閾惰璐﹀彿")
+    private String bankAccount;
+
+    @ApiModelProperty("寮�鎴疯鍙�")
+    @Excel(name = "寮�鎴疯鍙�")
+    private String bankCode;
+
+    @ApiModelProperty("瀹㈡埛鍒嗙被锛氶浂鍞鎴凤紝杩涢攢鍟嗗鎴�")
+    @Excel(name = "瀹㈡埛鍒嗙被")
+    private String customerType;
+
+    @ApiModelProperty("鍒涘缓浜篒D")
+    @TableField(fill = FieldFill.INSERT)
+    private Long createUser;
+
+    @ApiModelProperty("閮ㄩ棬ID")
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+
+
+    @ApiModelProperty("璺熻繘绋嬪害")
+    @TableField(exist = false)
+    private String followUpLevel;
+
+    @ApiModelProperty("璺熻繘鏃堕棿")
+    @TableField(exist = false)
+    private Date followUpTime;
+
+
+    @TableField(exist = false)
+    private Long[] ids;
+
+    @TableField(exist = false)
+    private String addressPhone;
+
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerPrivatePool.java b/src/main/java/com/ruoyi/basic/pojo/CustomerPrivatePool.java
new file mode 100644
index 0000000..edf88d7
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerPrivatePool.java
@@ -0,0 +1,68 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.IdType;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+import com.ruoyi.framework.aspectj.lang.annotation.Excel;
+import io.swagger.annotations.ApiModel;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.Getter;
+import lombok.Setter;
+
+/**
+ * <p>
+ * 
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-16 04:43:00
+ */
+@Data
+@TableName("customer_private_pool")
+@ApiModel(value = "CustomerPrivatePool瀵硅薄", description = "")
+public class CustomerPrivatePool implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @ApiModelProperty("涓婚敭id")
+    @TableId(value = "id", type = IdType.AUTO)
+    private Long id;
+
+    @ApiModelProperty("瀹㈡埛id")
+    private Long customerId;
+
+    @ApiModelProperty("缁戝畾浜篿d")
+    private Long boundId;
+
+    @ApiModelProperty("鍒涘缓浜�")
+    @TableField(fill = FieldFill.INSERT)
+    private Integer createUser;
+
+    @ApiModelProperty("鏇存柊浜�")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private Integer updateUser;
+
+    @ApiModelProperty("鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+
+    @ApiModelProperty("鏇存柊鏃堕棿")
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    private LocalDateTime updateTime;
+
+    @ApiModelProperty("绫诲瀷鍖哄垎鍏捣瀹㈡埛鍜岀娴峰鎴� 榛樿鏄娴峰鎴�0 鍏捣1")
+    private Long type;
+
+    @ApiModelProperty("閮ㄩ棬id")
+    @TableField(fill = FieldFill.INSERT)
+    private Long deptId;
+
+    @ApiModelProperty("鍒犻櫎鏍囪瘑 榛樿0 1宸茬粡鍒犻櫎")
+    private Integer DeleteFlag;
+}
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java b/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
index d91c863..f2edcc5 100644
--- a/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
@@ -36,7 +36,7 @@
     /**
      * 鍏宠仈瀹㈡埛ID
      */
-    private Integer customerId;
+    private Integer customerPrivatePoolId;
 
     /**
      * 鎻愰啋寮�鍏� (0:鍏抽棴, 1:寮�鍚�)
diff --git a/src/main/java/com/ruoyi/basic/service/CustomerPrivatePoolService.java b/src/main/java/com/ruoyi/basic/service/CustomerPrivatePoolService.java
new file mode 100644
index 0000000..18ca371
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/CustomerPrivatePoolService.java
@@ -0,0 +1,39 @@
+package com.ruoyi.basic.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.CustomerPrivatePool;
+import com.baomidou.mybatisplus.extension.service.IService;
+
+import java.util.List;
+
+/**
+ * <p>
+ *  鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-16 04:43:00
+ */
+public interface CustomerPrivatePoolService extends IService<CustomerPrivatePool> {
+
+    IPage<CustomerPrivatePoolDto> listPage(Page<CustomerPrivatePoolDto> page, CustomerPrivatePoolDto customerPrivatePoolDto);
+
+    boolean deleteCustomerPrivatePool(Long id);
+
+    boolean together(CustomerPrivatePoolDto customerPrivatePool);
+
+    boolean add(CustomerPrivatePoolDto customerPrivatePool);
+
+    CustomerPrivatePoolDto getInfo(Long id);
+
+    Boolean updateCustomerPrivatePoolDto(CustomerPrivatePoolDto customerPrivatePoolDto);
+
+    CustomerPrivatePoolDto getbyId(Long id);
+
+    List<CustomerPrivatePoolDto> selectCustomerPrivatePoolDtoListByIds(List<Long> ids);
+
+    List<CustomerPrivatePoolDto> selectCustomerPrivatePoolDtoLists(CustomerPrivatePoolDto customerPrivatePoolDto);
+}
diff --git a/src/main/java/com/ruoyi/basic/service/CustomerPrivateService.java b/src/main/java/com/ruoyi/basic/service/CustomerPrivateService.java
new file mode 100644
index 0000000..e758157
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/CustomerPrivateService.java
@@ -0,0 +1,33 @@
+package com.ruoyi.basic.service;
+
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerPrivateDto;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.CustomerPrivate;
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ruoyi.framework.web.domain.AjaxResult;
+import com.ruoyi.framework.web.domain.R;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.List;
+
+/**
+ * <p>
+ * 瀹㈡埛妗f 鏈嶅姟绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-17 10:39:09
+ */
+public interface CustomerPrivateService extends IService<CustomerPrivate> {
+
+
+    Boolean add(CustomerPrivateDto customerPrivateDto);
+
+
+    Integer delete(List<Long> id);
+
+    R importData(MultipartFile file);
+}
diff --git a/src/main/java/com/ruoyi/basic/service/ICustomerService.java b/src/main/java/com/ruoyi/basic/service/ICustomerService.java
index 989e474..c27dd92 100644
--- a/src/main/java/com/ruoyi/basic/service/ICustomerService.java
+++ b/src/main/java/com/ruoyi/basic/service/ICustomerService.java
@@ -4,6 +4,7 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.IService;
 import com.ruoyi.basic.dto.CustomerDto;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import org.springframework.web.multipart.MultipartFile;
@@ -32,7 +33,7 @@
      * @param id 瀹㈡埛妗f涓婚敭
      * @return 瀹㈡埛璇︽儏DTO
      */
-    CustomerDto selectCustomerDetailById(Long id);
+    Customer selectCustomerDetailById(Long id);
 
     /**
      * 鏌ヨ瀹㈡埛妗f鍒楄〃
@@ -40,7 +41,6 @@
      * @param customer 瀹㈡埛妗f
      * @return 瀹㈡埛妗f闆嗗悎
      */
-    IPage<Customer> selectCustomerList(Page<Customer> page, Customer customer);
 
     /**
      * 鏂板瀹㈡埛妗f
@@ -78,4 +78,6 @@
     List<Customer> selectCustomerLists(Customer customer);
 
     AjaxResult importData(MultipartFile file);
+
+    IPage<CustomerDto> selectCustomerList(Page<CustomerDto> page, CustomerDto customer);
 }
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java
index 5637307..12c7e06 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerFollowUpServiceImpl.java
@@ -132,7 +132,7 @@
         }
 
         List<CustomerFollowUp> followUps = list(new LambdaQueryWrapper<CustomerFollowUp>()
-                .eq(CustomerFollowUp::getCustomerId, customerId));
+                .eq(CustomerFollowUp::getCustomerPrivatePoolId, customerId));
 
         if (followUps != null && !followUps.isEmpty()) {
             for (CustomerFollowUp followUp : followUps) {
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerPrivatePoolServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerPrivatePoolServiceImpl.java
new file mode 100644
index 0000000..0586c9b
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerPrivatePoolServiceImpl.java
@@ -0,0 +1,234 @@
+package com.ruoyi.basic.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
+import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerDto;
+import com.ruoyi.basic.dto.CustomerFollowUpDto;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.mapper.CustomerPrivateMapper;
+import com.ruoyi.basic.pojo.*;
+import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
+import com.ruoyi.basic.service.*;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.sales.mapper.SalesLedgerMapper;
+import com.ruoyi.sales.pojo.SalesLedger;
+import org.checkerframework.checker.units.qual.A;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.ZoneId;
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-16 04:43:00
+ */
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class CustomerPrivatePoolServiceImpl extends ServiceImpl<CustomerPrivatePoolMapper, CustomerPrivatePool> implements CustomerPrivatePoolService {
+
+    @Autowired
+    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
+
+    @Autowired
+    private CustomerFollowUpService customerFollowUpService;
+
+    @Autowired
+    private CustomerReturnVisitService customerReturnVisitService;
+
+    @Autowired
+    private ICustomerService customerService;
+
+    @Autowired
+    private CustomerFollowUpFileService customerFollowUpFileService;
+    @Autowired
+    private CustomerPrivateMapper customerPrivateMapper;
+
+
+    @Override
+    public IPage<CustomerPrivatePoolDto> listPage(Page<CustomerPrivatePoolDto> page, CustomerPrivatePoolDto customerPrivatePoolDto) {
+        IPage<CustomerPrivatePoolDto> customerPrivatePoolDtoIPage = customerPrivatePoolMapper.listPage(page, customerPrivatePoolDto);
+        List<Long> customerIds = customerPrivatePoolDtoIPage.getRecords().stream()
+                .map(CustomerPrivatePoolDto::getId )
+                .filter(Objects::nonNull)
+                .collect(Collectors.toList());
+
+        if (!org.springframework.util.CollectionUtils.isEmpty(customerIds)) {
+            Map<Long, CustomerFollowUp> latestFollowUpMap = getLatestFollowUpMap(customerIds);
+
+            customerPrivatePoolDtoIPage.getRecords().forEach(c -> {
+                String address = StringUtils.defaultString(c.getCompanyAddress(), "");
+                String phone = StringUtils.defaultString(c.getCompanyPhone(), "");
+                c.setAddressPhone(address + "(" + phone + ")");
+
+                CustomerFollowUp followUp = latestFollowUpMap.get(c.getId());
+                if (followUp != null) {
+                    c.setFollowUpLevel(followUp.getFollowUpLevel());
+                    c.setFollowUpTime(Date.from(
+                            followUp.getFollowUpTime().atZone(ZoneId.systemDefault()).toInstant()
+                    ));
+                }
+            });
+
+        }
+        return customerPrivatePoolDtoIPage;
+    }
+
+
+    private Map<Long, CustomerFollowUp> getLatestFollowUpMap(List<Long> customerIds) {
+        List<CustomerFollowUp> followUps = customerFollowUpService.list(
+                new LambdaQueryWrapper<CustomerFollowUp>()
+                        .in(CustomerFollowUp::getCustomerPrivatePoolId, customerIds)
+                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
+        );
+
+        return followUps.stream()
+                .collect(Collectors.toMap(
+                        CustomerFollowUp::getCustomerPrivatePoolId,
+                        followUp -> followUp,
+                        (existing, replacement) -> existing
+                ));
+    }
+
+    @Override
+    public boolean deleteCustomerPrivatePool(Long id) {
+        List<CustomerPrivatePool> list = this.list(new QueryWrapper<CustomerPrivatePool>().lambda().eq(CustomerPrivatePool::getCustomerId, id));
+
+        for (CustomerPrivatePool customerPrivatePool : list) {
+            customerFollowUpService.remove(new QueryWrapper<CustomerFollowUp>().lambda().eq(CustomerFollowUp::getCustomerPrivatePoolId, customerPrivatePool.getId()));
+            customerReturnVisitService.remove(new QueryWrapper<CustomerReturnVisit>().lambda().eq(CustomerReturnVisit::getCustomerPrivatePoolId, customerPrivatePool.getId()));
+        }
+        Customer byId = customerService.getById(id);
+        byId.setUsageStatus(0L);
+        byId.setUsageUser(0L);
+        customerService.updateById(byId);
+        list.stream().forEach(customerPrivatePool -> {
+            customerPrivatePool.setDeleteFlag(1);
+            customerPrivatePoolMapper.updateById(customerPrivatePool);
+        });
+        return true;
+    }
+
+    @Override
+    public boolean together(CustomerPrivatePoolDto customerPrivatePoolDto) {
+        List<CustomerPrivatePool> existingPools = this.list(new QueryWrapper<CustomerPrivatePool>().lambda().eq(CustomerPrivatePool::getCustomerId, customerPrivatePoolDto.getCustomerId()));
+
+        List<Long> existingBoundIds = existingPools.stream()
+                .map(CustomerPrivatePool::getBoundId)
+                .collect(Collectors.toList());
+
+        List<Long> newBoundIds = customerPrivatePoolDto.getBoundIds().stream()
+                .filter(boundId -> !existingBoundIds.contains(boundId))
+                .collect(Collectors.toList());
+
+        if (CollectionUtils.isEmpty(newBoundIds)) {
+            return true;
+        }
+        for (Long id : customerPrivatePoolDto.getBoundIds()) {
+            CustomerPrivatePool customerPrivatePool = new CustomerPrivatePool();
+            customerPrivatePool.setCustomerId(customerPrivatePoolDto.getCustomerId());
+            customerPrivatePool.setBoundId(id);
+            customerPrivatePool.setType(1L);
+            this.save(customerPrivatePool);
+        }
+        return true;
+    }
+
+    @Override
+    public boolean add(CustomerPrivatePoolDto customerPrivatePool) {
+        customerPrivatePool.setType(1L);
+        this.save(customerPrivatePool);
+        Customer byId = customerService.getById(customerPrivatePool.getCustomerId());
+        if (byId != null) {
+            byId.setUsageStatus(1L);
+            byId.setUsageUser(customerPrivatePool.getBoundId());
+            return customerService.updateById(byId);
+        }
+        throw new RuntimeException("瀹㈡埛涓嶅瓨鍦�");
+
+    }
+
+    @Override
+    public CustomerPrivatePoolDto getInfo(Long id) {
+        CustomerPrivatePoolDto customerPrivatePool = customerPrivatePoolMapper.selectInfo(id);
+        if (customerPrivatePool == null) {
+            return null;
+        }
+
+        // 鏌ヨ璺熻繘璁板綍
+        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
+                new LambdaQueryWrapper<CustomerFollowUp>()
+                        .eq(CustomerFollowUp::getCustomerPrivatePoolId, id)
+                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
+        );
+        if (!CollectionUtils.isEmpty(followUpList)) {
+            List<CustomerFollowUpDto> followUpDtoList = followUpList.stream().map(followUp -> {
+                CustomerFollowUpDto followUpDto = new CustomerFollowUpDto();
+                BeanUtils.copyProperties(followUp, followUpDto);
+
+                // 鏌ヨ闄勪欢
+                List<CustomerFollowUpFile> fileList = customerFollowUpFileService.list(
+                        new LambdaQueryWrapper<CustomerFollowUpFile>()
+                                .eq(CustomerFollowUpFile::getFollowUpId, followUp.getId())
+                );
+                followUpDto.setFileList(fileList);
+
+                return followUpDto;
+            }).collect(Collectors.toList());
+
+            customerPrivatePool.setFollowUpList(followUpDtoList);
+        }
+
+        return customerPrivatePool;
+    }
+
+    @Override
+    public Boolean updateCustomerPrivatePoolDto(CustomerPrivatePoolDto customerPrivatePoolDto) {
+        if (customerPrivatePoolDto.getType() == 0L) {
+            CustomerPrivate byId = customerPrivateMapper.selectById(customerPrivatePoolDto.getCustomerId());
+            BeanUtils.copyProperties(customerPrivatePoolDto, byId);
+            byId.setId(customerPrivatePoolDto.getCustomerId());
+            customerPrivateMapper.updateById(byId);
+        } else if (customerPrivatePoolDto.getType() == 1L) {
+            Customer customer = customerService.getById(customerPrivatePoolDto.getCustomerId());
+            BeanUtils.copyProperties(customerPrivatePoolDto, customer);
+            customer.setId(customerPrivatePoolDto.getCustomerId());
+            customerService.updateById(customer);
+        }
+        return true;
+    }
+
+    @Override
+    public CustomerPrivatePoolDto getbyId(Long id) {
+        CustomerPrivatePoolDto customerPrivatePool = customerPrivatePoolMapper.selectInfo(id);
+        return customerPrivatePool;
+    }
+
+    @Override
+    public List<CustomerPrivatePoolDto> selectCustomerPrivatePoolDtoListByIds(List<Long> ids) {
+        ArrayList<CustomerPrivatePoolDto> customerPrivatePoolDtos = new ArrayList<>();
+        for (Long id : ids) {
+            CustomerPrivatePoolDto customerPrivatePoolDto = customerPrivatePoolMapper.selectInfo(id);
+            customerPrivatePoolDtos.add(customerPrivatePoolDto);
+        }
+        return customerPrivatePoolDtos;
+    }
+
+    @Override
+    public List<CustomerPrivatePoolDto> selectCustomerPrivatePoolDtoLists(CustomerPrivatePoolDto customerPrivatePoolDto) {
+
+        return customerPrivatePoolMapper.selectInfos();
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerPrivateServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerPrivateServiceImpl.java
new file mode 100644
index 0000000..3edeaa0
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerPrivateServiceImpl.java
@@ -0,0 +1,112 @@
+package com.ruoyi.basic.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.ruoyi.basic.dto.CustomerPrivateDto;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
+import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
+import com.ruoyi.basic.pojo.*;
+import com.ruoyi.basic.mapper.CustomerPrivateMapper;
+import com.ruoyi.basic.service.CustomerFollowUpService;
+import com.ruoyi.basic.service.CustomerPrivateService;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ruoyi.basic.service.CustomerReturnVisitService;
+import com.ruoyi.common.utils.SecurityUtils;
+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 org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.util.CollectionUtils;
+import org.springframework.web.multipart.MultipartFile;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * <p>
+ * 瀹㈡埛妗f 鏈嶅姟瀹炵幇绫�
+ * </p>
+ *
+ * @author 鑺杞欢锛堟睙鑻忥級鏈夐檺鍏徃
+ * @since 2026-04-17 10:39:09
+ */
+@Service
+@Transactional(rollbackFor = Exception.class)
+public class CustomerPrivateServiceImpl extends ServiceImpl<CustomerPrivateMapper, CustomerPrivate> implements CustomerPrivateService {
+
+
+    @Autowired
+    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
+
+    @Autowired
+    private CustomerFollowUpService customerFollowUpService;
+
+    @Autowired
+    private CustomerReturnVisitService customerReturnVisitService;
+    @Autowired
+    private SalesLedgerMapper salesLedgerMapper;
+
+
+    @Override
+    public Boolean add(CustomerPrivateDto customerPrivateDto) {
+        //鏂板绉佹捣 瀹㈡埛
+        this.save(customerPrivateDto);
+        //鏂板绉佹捣璁板綍
+        CustomerPrivatePool customerPrivatePool = new CustomerPrivatePool();
+        customerPrivatePool.setCustomerId(customerPrivateDto.getId());
+        customerPrivatePool.setBoundId(SecurityUtils.getLoginUser().getUserId());
+        customerPrivatePoolMapper.insert(customerPrivatePool);
+        return true;
+    }
+
+
+    @Override
+    public Integer delete(List<Long> ids) {
+        List<CustomerPrivatePool> customerPrivatePools = customerPrivatePoolMapper.selectList(new QueryWrapper<CustomerPrivatePool>().lambda().in(CustomerPrivatePool::getId, ids));
+        List<SalesLedger> salesLedgers = salesLedgerMapper.selectList(new QueryWrapper<SalesLedger>().lambda().in(SalesLedger::getCustomerId, customerPrivatePools.stream().map(CustomerPrivatePool::getCustomerId).collect(Collectors.toList())));
+        if (!CollectionUtils.isEmpty(salesLedgers)) {
+            throw new RuntimeException("瀹㈡埛鏈夐攢鍞悎鍚岋紝璇峰厛鍒犻櫎閿�鍞悎鍚�");
+        }
+        if (CollectionUtils.isEmpty(customerPrivatePools)) {
+            throw new RuntimeException("瀹㈡埛涓嶅瓨鍦�");
+        }
+        customerFollowUpService.remove(new QueryWrapper<CustomerFollowUp>().lambda().in(CustomerFollowUp::getCustomerPrivatePoolId, customerPrivatePools.stream().map(CustomerPrivatePool::getCustomerId).collect(Collectors.toList())));
+        customerReturnVisitService.remove(new QueryWrapper<CustomerReturnVisit>().lambda().in(CustomerReturnVisit::getCustomerPrivatePoolId, customerPrivatePools.stream().map(CustomerPrivatePool::getCustomerId).collect(Collectors.toList())));
+        customerPrivatePools.stream().forEach(customerPrivatePool -> {
+            customerPrivatePool.setDeleteFlag(1);
+            customerPrivatePoolMapper.updateById(customerPrivatePool);
+        });
+        return 1;
+
+    }
+
+    @Override
+    public R importData(MultipartFile file) {
+        try {
+            ExcelUtil<CustomerPrivate> util = new ExcelUtil<CustomerPrivate>(CustomerPrivate.class);
+            List<CustomerPrivate> userList = util.importExcel(file.getInputStream());
+            if (CollectionUtils.isEmpty(userList)) {
+                return R.fail("妯℃澘閿欒鎴栧鍏ユ暟鎹负绌�");
+            }
+            for (CustomerPrivate user : userList) {
+                CustomerPrivateDto customerPrivateDto = new CustomerPrivateDto();
+                BeanUtils.copyProperties(user, customerPrivateDto);
+                this.add(customerPrivateDto);
+            }
+            return R.ok(true);
+        } catch (Exception e) {
+            e.printStackTrace();
+            return R.fail("瀵煎叆澶辫触");
+        }
+    }
+}
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java
index 0186349..58bc422 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java
@@ -75,7 +75,7 @@
             throw new ServiceException("瀹㈡埛ID涓嶈兘涓虹┖");
         }
         LambdaQueryWrapper<CustomerReturnVisit> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(CustomerReturnVisit::getCustomerId, customerId);
+        queryWrapper.eq(CustomerReturnVisit::getCustomerPrivatePoolId, customerId);
         CustomerReturnVisit returnVisit = baseMapper.selectOne(queryWrapper);
 
         if (returnVisit == null) {
@@ -94,7 +94,7 @@
             throw new ServiceException("瀹㈡埛ID涓嶈兘涓虹┖");
         }
         LambdaQueryWrapper<CustomerReturnVisit> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(CustomerReturnVisit::getCustomerId, customerId);
+        queryWrapper.eq(CustomerReturnVisit::getCustomerPrivatePoolId, customerId);
         List<CustomerReturnVisit> returnVisits = baseMapper.selectList(queryWrapper);
 
         for (CustomerReturnVisit returnVisit : returnVisits) {
@@ -124,7 +124,7 @@
         if (returnVisit == null) {
             throw new ServiceException("鍥炶鎻愰啋鏁版嵁涓嶈兘涓虹┖");
         }
-        if (returnVisit.getCustomerId() == null) {
+        if (returnVisit.getCustomerPrivatePoolId() == null) {
             throw new ServiceException("瀹㈡埛ID涓嶈兘涓虹┖");
         }
         if (returnVisit.getReminderTime() == null) {
diff --git a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
index 58810c9..0f7b58d 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -1,8 +1,6 @@
 package com.ruoyi.basic.service.impl;
 
 
-import cn.hutool.core.date.DateUtil;
-import cn.hutool.core.date.LocalDateTimeUtil;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
@@ -11,10 +9,13 @@
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.basic.dto.CustomerDto;
 import com.ruoyi.basic.dto.CustomerFollowUpDto;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
 import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
 import com.ruoyi.basic.pojo.Customer;
 import com.ruoyi.basic.pojo.CustomerFollowUp;
 import com.ruoyi.basic.pojo.CustomerFollowUpFile;
+import com.ruoyi.basic.pojo.CustomerPrivatePool;
 import com.ruoyi.basic.service.CustomerFollowUpFileService;
 import com.ruoyi.basic.service.CustomerFollowUpService;
 import com.ruoyi.basic.service.CustomerReturnVisitService;
@@ -30,6 +31,7 @@
 import lombok.AllArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
@@ -51,13 +53,18 @@
 @AllArgsConstructor
 @Slf4j
 public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService {
-    private final SalesLedgerMapper salesLedgerMapper;
+    @Autowired
+    private  SalesLedgerMapper salesLedgerMapper;
+    @Autowired
+    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
+    @Autowired
     private CustomerMapper customerMapper;
 
+    @Autowired
     private CustomerFollowUpService customerFollowUpService;
-
+    @Autowired
     private CustomerFollowUpFileService customerFollowUpFileService;
-
+    @Autowired
     private CustomerReturnVisitService customerReturnVisitService;
 
     /**
@@ -78,41 +85,8 @@
      * @return 瀹㈡埛璇︽儏DTO
      */
     @Override
-    public CustomerDto selectCustomerDetailById(Long id) {
-        Customer customer = customerMapper.selectById(id);
-        if (customer == null) {
-            return null;
-        }
-
-        CustomerDto dto = new CustomerDto();
-        BeanUtils.copyProperties(customer, dto);
-
-        // 鏌ヨ璺熻繘璁板綍
-        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
-                new LambdaQueryWrapper<CustomerFollowUp>()
-                        .eq(CustomerFollowUp::getCustomerId, id)
-                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
-        );
-
-        if (!CollectionUtils.isEmpty(followUpList)) {
-            List<CustomerFollowUpDto> followUpDtoList = followUpList.stream().map(followUp -> {
-                CustomerFollowUpDto followUpDto = new CustomerFollowUpDto();
-                BeanUtils.copyProperties(followUp, followUpDto);
-
-                // 鏌ヨ闄勪欢
-                List<CustomerFollowUpFile> fileList = customerFollowUpFileService.list(
-                        new LambdaQueryWrapper<CustomerFollowUpFile>()
-                                .eq(CustomerFollowUpFile::getFollowUpId, followUp.getId())
-                );
-                followUpDto.setFileList(fileList);
-
-                return followUpDto;
-            }).collect(Collectors.toList());
-
-            dto.setFollowUpList(followUpDtoList);
-        }
-
-        return dto;
+    public Customer selectCustomerDetailById(Long id) {
+        return this.getById( id);
     }
 
     /**
@@ -122,62 +96,53 @@
      * @return 瀹㈡埛妗f
      */
     @Override
-    public IPage<Customer> selectCustomerList(Page<Customer> page, Customer customer) {
-        // 1. 澶勭悊绌哄�煎満鏅紙鍙傛暟鏍¢獙锛�
-        if (page == null) {
-            page = Page.of(1, 10); // 榛樿绗�1椤碉紝姣忛〉10鏉℃暟鎹�
-        }
-        if (customer == null) {
-            customer = new Customer(); // 閬垮厤绌哄璞″鑷寸殑NPE
+    public IPage<CustomerDto> selectCustomerList(Page<CustomerDto> page, CustomerDto customer) {
+        IPage<CustomerDto> customerPage = customerMapper.listPage(page, customer);
+
+        List<CustomerDto> records = customerPage.getRecords();
+        if (CollectionUtils.isEmpty(records)) {
+            return customerPage;
         }
 
-        // 2. 鏋勫缓鏌ヨ鏉′欢锛堝寮虹┖鍊煎畨鍏級
-        LambdaQueryWrapper<Customer> queryWrapper = new LambdaQueryWrapper<>();
-        String customerName = customer.getCustomerName();
-        String customerType = customer.getCustomerType();
-        if (StringUtils.isNotBlank(customerName)) {
-            queryWrapper.like(Customer::getCustomerName, customerName);
-        }
-        if (StringUtils.isNotBlank(customerType)) {
-            queryWrapper.like(Customer::getCustomerType, customerType);
-        }
-
-        // 3. 鎵ц鍒嗛〉鏌ヨ锛堜繚鐣欏垎椤靛厓鏁版嵁锛�
-        IPage<Customer> customerPage = customerMapper.selectPage(page, queryWrapper);
-
-        // 4. 鏁版嵁澶勭悊锛堝寮虹┖鍊煎畨鍏� & 浠g爜鍙鎬э級
-        List<Customer> processedList = customerPage.getRecords().stream()
-                .filter(Objects::nonNull) // 杩囨护绌哄璞★紙閬垮厤鍚庣画鎿嶄綔NPE锛�
-                .peek(c -> {
-                    // 瀹夊叏鑾峰彇瀛楁锛岄伩鍏峮ull鍊兼嫾鎺�
-                    String address = StringUtils.defaultString(c.getCompanyAddress(), "");
-                    String phone = StringUtils.defaultString(c.getCompanyPhone(), "");
-                    c.setAddressPhone(address + "(" + phone + ")");
-
-                    // 鏌ヨ鏈�鏂扮殑璺熻繘璁板綍
-                    CustomerFollowUp followUp = customerFollowUpService.getOne(
-                            new LambdaQueryWrapper<CustomerFollowUp>()
-                                    .eq(CustomerFollowUp::getCustomerId, c.getId())
-                                    .orderByDesc(CustomerFollowUp::getFollowUpTime)
-                                    .last("LIMIT 1")
-                    );
-
-                    if (followUp != null) {
-                        c.setFollowUpLevel(followUp.getFollowUpLevel());
-                        c.setFollowUpTime(
-                                Date.from(
-                                        followUp.getFollowUpTime().atZone(ZoneId.systemDefault()).toInstant()
-                                )
-                        );
-                    }
-                })
+        List<Long> customerIds = records.stream()
+                .map(CustomerDto::getId)
+                .filter(Objects::nonNull)
                 .collect(Collectors.toList());
 
-        // 5. 鏇存柊鍒嗛〉缁撴灉涓殑鏁版嵁锛堜繚鎸佸垎椤典俊鎭畬鏁达級
-        IPage<Customer> resultPage = new Page<>(customerPage.getCurrent(), customerPage.getSize(), customerPage.getTotal());
-        resultPage.setRecords(processedList);
+        if (!CollectionUtils.isEmpty(customerIds)) {
+            Map<Long, CustomerFollowUp> latestFollowUpMap = getLatestFollowUpMap(customerIds);
 
-        return customerPage; // 杩斿洖鍖呭惈鍒嗛〉淇℃伅鐨処Page瀵硅薄
+            records.forEach(c -> {
+                String address = StringUtils.defaultString(c.getCompanyAddress(), "");
+                String phone = StringUtils.defaultString(c.getCompanyPhone(), "");
+                c.setAddressPhone(address + "(" + phone + ")");
+
+                CustomerFollowUp followUp = latestFollowUpMap.get(c.getId());
+                if (followUp != null) {
+                    c.setFollowUpLevel(followUp.getFollowUpLevel());
+                    c.setFollowUpTime(Date.from(
+                            followUp.getFollowUpTime().atZone(ZoneId.systemDefault()).toInstant()
+                    ));
+                }
+            });
+        }
+
+        return customerPage;
+    }
+
+    private Map<Long, CustomerFollowUp> getLatestFollowUpMap(List<Long> customerIds) {
+        List<CustomerFollowUp> followUps = customerFollowUpService.list(
+                new LambdaQueryWrapper<CustomerFollowUp>()
+                        .in(CustomerFollowUp::getCustomerPrivatePoolId, customerIds)
+                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
+        );
+
+        return followUps.stream()
+                .collect(Collectors.toMap(
+                        CustomerFollowUp::getCustomerPrivatePoolId,
+                        followUp -> followUp,
+                        (existing, replacement) -> existing
+                ));
     }
 
     /**
diff --git a/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java b/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
index 245acda..2b57ee7 100644
--- a/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
+++ b/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
@@ -76,7 +76,7 @@
         }
 
         try {
-            unipushService.sendReturnVisitReminder(returnVisitId, client.getCid(), returnVisit.getContent(), returnVisit.getCustomerId());
+            unipushService.sendReturnVisitReminder(returnVisitId, client.getCid(), returnVisit.getContent(), returnVisit.getCustomerPrivatePoolId());
             CustomerReturnVisit updateObj = new CustomerReturnVisit();
             updateObj.setId(returnVisitId);
             updateObj.setIsCompleted(1);
diff --git a/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java b/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
index 3978947..f2e1d08 100644
--- a/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
+++ b/src/main/java/com/ruoyi/common/config/IgnoreTableConfig.java
@@ -36,6 +36,8 @@
         IGNORE_TABLES.add("gen_table");
         IGNORE_TABLES.add("sys_notice");
         IGNORE_TABLES.add("sys_user_client");
-        IGNORE_TABLES.add("gen_table_column");
+        IGNORE_TABLES.add("product_model");
+        IGNORE_TABLES.add("product");
+
     }
 }
diff --git a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
index 3b0cc55..e2c11cf 100644
--- a/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
+++ b/src/main/java/com/ruoyi/sales/service/impl/SalesLedgerServiceImpl.java
@@ -9,10 +9,13 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.account.service.AccountIncomeService;
+import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
 import com.ruoyi.basic.mapper.CustomerMapper;
+import com.ruoyi.basic.mapper.CustomerPrivatePoolMapper;
 import com.ruoyi.basic.mapper.ProductMapper;
 import com.ruoyi.basic.mapper.ProductModelMapper;
 import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.pojo.CustomerPrivatePool;
 import com.ruoyi.common.enums.FileNameType;
 import com.ruoyi.common.enums.SaleEnum;
 import com.ruoyi.common.exception.base.BaseException;
@@ -128,6 +131,8 @@
     ;
     @Autowired
     private SysUserMapper sysUserMapper;
+    @Autowired
+    private CustomerPrivatePoolMapper customerPrivatePoolMapper;
 
     @Override
     public List<SalesLedger> selectSalesLedgerList(SalesLedgerDto salesLedgerDto) {
@@ -594,7 +599,7 @@
     public int addOrUpdateSalesLedger(SalesLedgerDto salesLedgerDto) {
         try {
             // 1. 鏍¢獙瀹㈡埛淇℃伅
-            Customer customer = customerMapper.selectById(salesLedgerDto.getCustomerId());
+            CustomerPrivatePoolDto customer = customerPrivatePoolMapper.selectInfo(salesLedgerDto.getCustomerId());
             if (customer == null) {
                 throw new BaseException("瀹㈡埛涓嶅瓨鍦�");
             }
diff --git a/src/main/resources/mapper/basic/CustomerMapper.xml b/src/main/resources/mapper/basic/CustomerMapper.xml
new file mode 100644
index 0000000..c0bc2fa
--- /dev/null
+++ b/src/main/resources/mapper/basic/CustomerMapper.xml
@@ -0,0 +1,33 @@
+<?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="com.ruoyi.basic.mapper.CustomerMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.basic.pojo.Customer">
+        <id column="id" property="id" />
+    </resultMap>
+    <select id="listPage" resultType="com.ruoyi.basic.dto.CustomerDto">
+        select
+        c.*,
+        u.user_name usage_user_name,
+        (
+        select group_concat(u2.user_name separator ', ')
+        from customer_private_pool cpp2
+        left join sys_user u2 on cpp2.bound_id = u2.user_id
+        where cpp2.customer_id = c.id
+        and cpp2.bound_id != c.usage_user
+        ) as together_user_names
+        from customer c
+        left join sys_user u on c.usage_user = u.user_id
+        <where>
+            <if test="c.customerName != null and c.customerName != ''">
+                and customer_name like concat('%', #{c.customerName}, '%')
+            </if>
+            <if test="c.customerType != null and c.customerType != ''">
+                and customer_type = #{c.customerType}
+            </if>
+        </where>
+    </select>
+
+
+</mapper>
diff --git a/src/main/resources/mapper/basic/CustomerPrivateMapper.xml b/src/main/resources/mapper/basic/CustomerPrivateMapper.xml
new file mode 100644
index 0000000..9a8d68c
--- /dev/null
+++ b/src/main/resources/mapper/basic/CustomerPrivateMapper.xml
@@ -0,0 +1,25 @@
+<?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="com.ruoyi.basic.mapper.CustomerPrivateMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.basic.pojo.CustomerPrivate">
+        <id column="id" property="id" />
+        <result column="customer_name" property="customerName" />
+        <result column="taxpayer_identification_number" property="taxpayerIdentificationNumber" />
+        <result column="company_address" property="companyAddress" />
+        <result column="company_phone" property="companyPhone" />
+        <result column="contact_person" property="contactPerson" />
+        <result column="contact_phone" property="contactPhone" />
+        <result column="maintainer" property="maintainer" />
+        <result column="maintenance_time" property="maintenanceTime" />
+        <result column="tenant_id" property="tenantId" />
+        <result column="basic_bank_account" property="basicBankAccount" />
+        <result column="bank_account" property="bankAccount" />
+        <result column="bank_code" property="bankCode" />
+        <result column="customer_type" property="customerType" />
+        <result column="create_user" property="createUser" />
+        <result column="dept_id" property="deptId" />
+    </resultMap>
+
+</mapper>
diff --git a/src/main/resources/mapper/basic/CustomerPrivatePoolMapper.xml b/src/main/resources/mapper/basic/CustomerPrivatePoolMapper.xml
new file mode 100644
index 0000000..08e16e4
--- /dev/null
+++ b/src/main/resources/mapper/basic/CustomerPrivatePoolMapper.xml
@@ -0,0 +1,97 @@
+<?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="com.ruoyi.basic.mapper.CustomerPrivatePoolMapper">
+
+    <!-- 閫氱敤鏌ヨ鏄犲皠缁撴灉 -->
+    <resultMap id="BaseResultMap" type="com.ruoyi.basic.pojo.CustomerPrivatePool">
+        <id column="id" property="id" />
+        <result column="customer_id" property="customerId" />
+        <result column="bound_id" property="boundId" />
+        <result column="create_user" property="createUser" />
+        <result column="update_user" property="updateUser" />
+        <result column="create_time" property="createTime" />
+        <result column="update_time" property="updateTime" />
+    </resultMap>
+    <select id="listPage" resultType="com.ruoyi.basic.dto.CustomerPrivatePoolDto">
+        select cpp.id,
+        cpp.bound_id,
+        cpp.type,
+        coalesce(c.id, cp.id) as customer_id,
+        coalesce(c.customer_name, cp.customer_name) as customer_name,
+        coalesce(c.customer_type, cp.customer_type) as customer_type,
+        coalesce(c.taxpayer_identification_number, cp.taxpayer_identification_number) as taxpayer_identification_number,
+        coalesce(c.company_address, cp.company_address) as company_address,
+        coalesce(c.company_phone, cp.company_phone) as company_phone,
+        coalesce(c.contact_person, cp.contact_person) as contact_person,
+        coalesce(c.contact_phone, cp.contact_phone) as contact_phone,
+        coalesce(c.maintainer, cp.maintainer) as maintainer,
+        coalesce(c.maintenance_time, cp.maintenance_time) as maintenance_time,
+        coalesce(c.tenant_id, cp.tenant_id) as tenant_id,
+        coalesce(c.basic_bank_account, cp.basic_bank_account) as basic_bank_account,
+        coalesce(c.bank_account, cp.bank_account) as bank_account,
+        coalesce(c.bank_code, cp.bank_code) as bank_code
+        from customer_private_pool cpp
+        left join customer c on c.id = cpp.customer_id and cpp.type = 1
+        left join customer_private cp on cp.id = cpp.customer_id and cpp.type = 0
+        <where>
+            cpp.delete_flag = 0
+            <if test="c.customerName != null and c.customerName != ''">
+                and c.customer_name like concat('%', #{c.customerName}, '%')
+            </if>
+            <if test="c.boundId != null">
+                and cpp.bound_id = #{c.boundId}
+            </if>
+        </where>
+        order by cpp.id desc
+    </select>
+    <select id="selectInfo" resultType="com.ruoyi.basic.dto.CustomerPrivatePoolDto">
+        select cpp.id,
+               cpp.bound_id,
+               cpp.type,
+               coalesce(c.id, cp.id) as customer_id,
+               coalesce(c.customer_name, cp.customer_name) as customer_name,
+               coalesce(c.customer_type, cp.customer_type) as customer_type,
+               coalesce(c.taxpayer_identification_number, cp.taxpayer_identification_number) as taxpayer_identification_number,
+               coalesce(c.company_address, cp.company_address) as company_address,
+               coalesce(c.company_phone, cp.company_phone) as company_phone,
+               coalesce(c.contact_person, cp.contact_person) as contact_person,
+               coalesce(c.contact_phone, cp.contact_phone) as contact_phone,
+               coalesce(c.maintainer, cp.maintainer) as maintainer,
+               coalesce(c.maintenance_time, cp.maintenance_time) as maintenance_time,
+               coalesce(c.tenant_id, cp.tenant_id) as tenant_id,
+               coalesce(c.basic_bank_account, cp.basic_bank_account) as basic_bank_account,
+               coalesce(c.bank_account, cp.bank_account) as bank_account,
+               coalesce(c.bank_code, cp.bank_code) as bank_code
+        from customer_private_pool cpp
+                 left join customer c on c.id = cpp.customer_id and cpp.type = 1
+                 left join customer_private cp on cp.id = cpp.customer_id and cpp.type = 0
+        <where>
+            <if test="id != null">
+                and cpp.id = #{id}
+            </if>
+        </where>
+    </select>
+    <select id="selectInfos" resultType="com.ruoyi.basic.dto.CustomerPrivatePoolDto">
+        select cpp.id,
+               cpp.bound_id,
+               cpp.type,
+               coalesce(c.id, cp.id) as customer_id,
+               coalesce(c.customer_name, cp.customer_name) as customer_name,
+               coalesce(c.customer_type, cp.customer_type) as customer_type,
+               coalesce(c.taxpayer_identification_number, cp.taxpayer_identification_number) as taxpayer_identification_number,
+               coalesce(c.company_address, cp.company_address) as company_address,
+               coalesce(c.company_phone, cp.company_phone) as company_phone,
+               coalesce(c.contact_person, cp.contact_person) as contact_person,
+               coalesce(c.contact_phone, cp.contact_phone) as contact_phone,
+               coalesce(c.maintainer, cp.maintainer) as maintainer,
+               coalesce(c.maintenance_time, cp.maintenance_time) as maintenance_time,
+               coalesce(c.tenant_id, cp.tenant_id) as tenant_id,
+               coalesce(c.basic_bank_account, cp.basic_bank_account) as basic_bank_account,
+               coalesce(c.bank_account, cp.bank_account) as bank_account,
+               coalesce(c.bank_code, cp.bank_code) as bank_code
+        from customer_private_pool cpp
+                 left join customer c on c.id = cpp.customer_id and cpp.type = 1
+                 left join customer_private cp on cp.id = cpp.customer_id and cpp.type = 0
+    </select>
+
+</mapper>
diff --git a/src/main/resources/mapper/sales/InvoiceLedgerMapper.xml b/src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
index 2874f48..5454640 100644
--- a/src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
+++ b/src/main/resources/mapper/sales/InvoiceLedgerMapper.xml
@@ -123,7 +123,7 @@
                 T1.customer_name LIKE CONCAT ('%',#{invoiceLedgerDto.searchText},'%')
             </if>
         </where>
-        GROUP BY T1.customer_name
+        GROUP BY T1.customer_name,t1.customer_id
     </select>
 
     <select id="invoiceLedgerProductInfo" resultType="com.ruoyi.sales.dto.InvoiceRegistrationProductDto">

--
Gitblit v1.9.3