From c383c8ca7053005ffa3ee58efd89956fbf52c9ea Mon Sep 17 00:00:00 2001
From: huminmin <mac@MacBook-Pro.local>
Date: 星期四, 07 五月 2026 11:34:19 +0800
Subject: [PATCH] 重构客户档案

---
 src/main/java/com/ruoyi/basic/pojo/Customer.java                               |    5 +
 src/main/java/com/ruoyi/basic/pojo/CustomerUser.java                           |   43 ++++++++++
 src/main/resources/mapper/basic/CustomerMapper.xml                             |   18 +++-
 src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java                |    2 
 src/main/java/com/ruoyi/basic/vo/CustomerVo.java                               |   14 +++
 src/main/java/com/ruoyi/basic/service/ICustomerService.java                    |    7 +
 src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java            |   75 +++++++++++++++++-
 src/main/java/com/ruoyi/basic/dto/CustomerDto.java                             |    1 
 src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java                       |    2 
 src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java                    |    2 
 src/main/java/com/ruoyi/basic/controller/CustomerController.java               |   19 ++++
 src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java        |    2 
 src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java |    6 
 doc/create_table_customer_user.sql                                             |   10 ++
 14 files changed, 189 insertions(+), 17 deletions(-)

diff --git a/doc/create_table_customer_user.sql b/doc/create_table_customer_user.sql
new file mode 100644
index 0000000..dacbfb4
--- /dev/null
+++ b/doc/create_table_customer_user.sql
@@ -0,0 +1,10 @@
+drop table if exists customer_user;
+create table customer_user
+(
+    id          bigint auto_increment
+        primary key,
+    customer_id bigint not null default 0 comment '瀹㈡埛id',
+    user_id     bigint not null default 0 comment '鐢ㄦ埛id',
+    create_time datetime null comment '褰曞叆鏃堕棿',
+    tenant_id   bigint not null default 0 comment '绉熸埛id'
+);
diff --git a/src/main/java/com/ruoyi/basic/controller/CustomerController.java b/src/main/java/com/ruoyi/basic/controller/CustomerController.java
index 9aa6570..e2373e6 100644
--- a/src/main/java/com/ruoyi/basic/controller/CustomerController.java
+++ b/src/main/java/com/ruoyi/basic/controller/CustomerController.java
@@ -121,4 +121,23 @@
     }
 
 
+    /**
+     * 鍒嗛厤瀹㈡埛
+     */
+    @Log(title = "瀹㈡埛妗f", businessType = BusinessType.OTHER)
+    @PostMapping("/assignCustomer")
+    public AjaxResult assignCustomer(@RequestBody CustomerDto customer) {
+        customerService.assignCustomer(customer);
+        return AjaxResult.success();
+    }
+
+    /**
+     * 鍥炴敹瀹㈡埛
+     */
+    @Log(title = "瀹㈡埛妗f", businessType = BusinessType.OTHER)
+    @PostMapping("/recycleCustomer")
+    public AjaxResult recycleCustomer(@RequestBody CustomerDto customer) {
+        customerService.recycleCustomer(customer);
+        return AjaxResult.success();
+    }
 }
diff --git a/src/main/java/com/ruoyi/basic/dto/CustomerDto.java b/src/main/java/com/ruoyi/basic/dto/CustomerDto.java
index 630119f..d2790d2 100644
--- a/src/main/java/com/ruoyi/basic/dto/CustomerDto.java
+++ b/src/main/java/com/ruoyi/basic/dto/CustomerDto.java
@@ -24,5 +24,4 @@
     private String usageUserName;
 
     private String togetherUserNames;
-
 }
diff --git a/src/main/java/com/ruoyi/basic/pojo/Customer.java b/src/main/java/com/ruoyi/basic/pojo/Customer.java
index 1b47163..21b918a 100644
--- a/src/main/java/com/ruoyi/basic/pojo/Customer.java
+++ b/src/main/java/com/ruoyi/basic/pojo/Customer.java
@@ -129,4 +129,9 @@
     @Schema(description = "浣跨敤鐘舵��")
     private Long usageStatus;
 
+    @ApiModelProperty(value = "绫诲瀷 0 绉佹捣瀹㈡埛 1 鍏捣瀹㈡埛")
+    private Integer type;
+
+    @ApiModelProperty(value = "鏄惁琚垎閰嶏細0-鏈垎閰嶏紝1-宸插垎閰�")
+    private Integer isAssigned;
 }
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java b/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
index 9f34f61..6b5fed1 100644
--- a/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
@@ -39,6 +39,8 @@
      */
     private Long customerPrivatePoolId;
 
+    private Long customerId;
+
     /**
      * 璺熻繘鏂瑰紡
      */
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java b/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
index f2edcc5..88768e4 100644
--- a/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
@@ -38,6 +38,8 @@
      */
     private Integer customerPrivatePoolId;
 
+    private Long customerId;
+
     /**
      * 鎻愰啋寮�鍏� (0:鍏抽棴, 1:寮�鍚�)
      */
diff --git a/src/main/java/com/ruoyi/basic/pojo/CustomerUser.java b/src/main/java/com/ruoyi/basic/pojo/CustomerUser.java
new file mode 100644
index 0000000..29da8ff
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/pojo/CustomerUser.java
@@ -0,0 +1,43 @@
+package com.ruoyi.basic.pojo;
+
+import com.baomidou.mybatisplus.annotation.*;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.io.Serializable;
+import java.time.LocalDateTime;
+
+@TableName(value = "customer")
+@Data
+public class CustomerUser implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 搴忓彿
+     */
+    @TableId(type = IdType.AUTO)
+    private Long id;
+
+    /**
+     * 瀹㈡埛id
+     */
+    private Long customerId;
+
+    /**
+     * 鐢ㄦ埛id
+     */
+    private Long userId;
+
+    /**
+     * 绉熸埛id
+     */
+    @TableField(fill = FieldFill.INSERT)
+    private Long tenantId;
+
+    /**
+     * 褰曞叆鏃堕棿
+     */
+    @ApiModelProperty(value = "鍒涘缓鏃堕棿")
+    @TableField(fill = FieldFill.INSERT)
+    private LocalDateTime createTime;
+}
diff --git a/src/main/java/com/ruoyi/basic/service/ICustomerService.java b/src/main/java/com/ruoyi/basic/service/ICustomerService.java
index c27dd92..3a300ea 100644
--- a/src/main/java/com/ruoyi/basic/service/ICustomerService.java
+++ b/src/main/java/com/ruoyi/basic/service/ICustomerService.java
@@ -6,6 +6,7 @@
 import com.ruoyi.basic.dto.CustomerDto;
 import com.ruoyi.basic.dto.CustomerPrivatePoolDto;
 import com.ruoyi.basic.pojo.Customer;
+import com.ruoyi.basic.vo.CustomerVo;
 import com.ruoyi.framework.web.domain.AjaxResult;
 import org.springframework.web.multipart.MultipartFile;
 
@@ -33,7 +34,7 @@
      * @param id 瀹㈡埛妗f涓婚敭
      * @return 瀹㈡埛璇︽儏DTO
      */
-    Customer selectCustomerDetailById(Long id);
+    CustomerVo selectCustomerDetailById(Long id);
 
     /**
      * 鏌ヨ瀹㈡埛妗f鍒楄〃
@@ -80,4 +81,8 @@
     AjaxResult importData(MultipartFile file);
 
     IPage<CustomerDto> selectCustomerList(Page<CustomerDto> page, CustomerDto customer);
+
+    void assignCustomer(CustomerDto customer);
+
+    void recycleCustomer(CustomerDto customer);
 }
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 9192d50..f2a1556 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::getCustomerPrivatePoolId, customerId);
+        queryWrapper.eq(CustomerReturnVisit::getCustomerId, 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::getCustomerPrivatePoolId, customerId);
+        queryWrapper.eq(CustomerReturnVisit::getCustomerId, customerId);
         List<CustomerReturnVisit> returnVisits = baseMapper.selectList(queryWrapper);
 
         for (CustomerReturnVisit returnVisit : returnVisits) {
@@ -124,7 +124,7 @@
         if (returnVisit == null) {
             throw new ServiceException("鍥炶鎻愰啋鏁版嵁涓嶈兘涓虹┖");
         }
-        if (returnVisit.getCustomerPrivatePoolId() == null) {
+        if (returnVisit.getCustomerId() == 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 b4b0232..959d906 100644
--- a/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
+++ b/src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -8,16 +8,20 @@
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ruoyi.basic.dto.CustomerDto;
+import com.ruoyi.basic.dto.CustomerFollowUpDto;
 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.CustomerFollowUpService;
 import com.ruoyi.basic.service.CustomerReturnVisitService;
 import com.ruoyi.basic.service.ICustomerService;
+import com.ruoyi.basic.vo.CustomerVo;
 import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.common.utils.bean.BeanUtils;
 import com.ruoyi.common.utils.poi.ExcelUtil;
 import com.ruoyi.framework.security.LoginUser;
 import com.ruoyi.framework.web.domain.AjaxResult;
@@ -30,6 +34,9 @@
 import org.springframework.util.CollectionUtils;
 import org.springframework.web.multipart.MultipartFile;
 
+
+import java.time.LocalDate;
+import java.time.LocalDateTime;
 import java.time.ZoneId;
 import java.util.*;
 import java.util.stream.Collectors;
@@ -70,8 +77,35 @@
      * @return 瀹㈡埛璇︽儏DTO
      */
     @Override
-    public Customer selectCustomerDetailById(Long id) {
-        return this.getById( id);
+    public CustomerVo selectCustomerDetailById(Long id) {
+        CustomerVo customerVo = new CustomerVo();
+        BeanUtils.copyProperties(this.getById(id), customerVo);
+
+        // 鏌ヨ璺熻繘璁板綍
+        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
+                new LambdaQueryWrapper<CustomerFollowUp>()
+                        .eq(CustomerFollowUp::getCustomerId, id)
+                        .orderByDesc(CustomerFollowUp::getFollowUpTime)
+        );
+        if (!com.baomidou.mybatisplus.core.toolkit.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());
+
+            customerVo.setFollowUpList(followUpDtoList);
+        }
+
+        return customerVo;
     }
 
     /**
@@ -172,15 +206,22 @@
         if (!salesLedgers.isEmpty()) {
             throw new RuntimeException("瀹㈡埛妗f涓嬫湁閿�鍞悎鍚岋紝璇峰厛鍒犻櫎閿�鍞悎鍚�");
         }
-        List<CustomerPrivatePool> customerPrivatePools = customerPrivatePoolMapper.selectList(new QueryWrapper<CustomerPrivatePool>().lambda().in(CustomerPrivatePool::getCustomerId, idList));
-        if (!customerPrivatePools.isEmpty()) {
-            throw new RuntimeException("瀹㈡埛妗f涓嬫湁瀹㈡埛绉佹捣锛岃鍏堟敹鍥炵娴锋暟鎹�");
+        // 鏌ヨ鏄惁鏈夊凡鍒嗛厤鐨勫叕娴峰鎴�
+        List<Customer> assignedPools = customerMapper.selectList(
+                new QueryWrapper<Customer>().lambda()
+                        .in(Customer::getId, idList)
+                        .eq(Customer::getType, 1).
+                        eq(Customer::getIsAssigned, 1)  // 鍏捣瀹㈡埛
+        );
+        if (!assignedPools.isEmpty()) {
+            throw new RuntimeException("瀹㈡埛妗f涓嬫湁宸插垎閰嶇殑鍏捣瀹㈡埛锛岃鍏堟敹鍥�");
         }
         //  鍒犻櫎瀹㈡埛鐨勫悓鏃朵篃闇�瑕佸垹闄ゅ搴旂殑瀹㈡埛璺熼殢銆侀檮浠跺拰鍥炶鎻愰啋
         for (Long id : ids) {
             customerFollowUpService.deleteByCustomerId(id);
             customerReturnVisitService.deleteByCustomerId(id);
         }
+        customerMapper.delete(new QueryWrapper<Customer>().lambda().in(Customer::getId, idList));
 
         return customerMapper.deleteBatchIds(idList);
     }
@@ -230,6 +271,30 @@
         ).collect(Collectors.toList());
     }
 
+    // 鍒嗛厤鍏捣瀹㈡埛缁欑娴�
+    @Override
+    public void assignCustomer(CustomerDto customerDto) {
+        Customer customer = customerMapper.selectById(customerDto.getId());
+        if (customer.getType() == 1 && customer.getIsAssigned() == 0) {  // 鍏捣涓斿彲鍒嗛厤
+            customer.setIsAssigned(1);
+            customer.setUsageStatus(1L);
+            customer.setUsageUser(customerDto.getUsageUser());
+            customerMapper.updateById(customer);
+        }
+    }
+
+    // 鍥炴敹绉佹捣瀹㈡埛鍒板叕娴�
+    @Override
+    public void recycleCustomer(CustomerDto customerDto) {
+        Customer customer = customerMapper.selectById(customerDto.getId());
+        if (customer.getType() == 1 && customer.getIsAssigned() == 1) {  // 鍏捣涓斿凡鍒嗛厤
+            customer.setIsAssigned(0);
+            customer.setUsageStatus(0L);
+            customer.setUsageUser(null);
+            customerMapper.updateById(customer);
+        }
+    }
+
     /**
      * 涓嬪垝绾垮懡鍚嶈浆椹煎嘲鍛藉悕
      */
diff --git a/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java b/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
index edc3b54..fbfb5b6 100644
--- a/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
+++ b/src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java
@@ -72,7 +72,7 @@
         }
 
         try {
-            unipushService.sendReturnVisitReminder(returnVisitId, client.getCid(), returnVisit.getContent(), returnVisit.getCustomerPrivatePoolId());
+            unipushService.sendReturnVisitReminder(returnVisitId, client.getCid(), returnVisit.getContent(), returnVisit.getCustomerId());
             CustomerReturnVisit updateObj = new CustomerReturnVisit();
             updateObj.setId(returnVisitId);
             updateObj.setIsCompleted(1);
diff --git a/src/main/java/com/ruoyi/basic/vo/CustomerVo.java b/src/main/java/com/ruoyi/basic/vo/CustomerVo.java
new file mode 100644
index 0000000..bb97a39
--- /dev/null
+++ b/src/main/java/com/ruoyi/basic/vo/CustomerVo.java
@@ -0,0 +1,14 @@
+package com.ruoyi.basic.vo;
+
+import com.ruoyi.basic.dto.CustomerFollowUpDto;
+import com.ruoyi.basic.pojo.Customer;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+
+import java.util.List;
+
+@Data
+public class CustomerVo extends Customer {
+    @ApiModelProperty(value = "璺熻繘璁板綍")
+    private List<CustomerFollowUpDto> followUpList;
+}
diff --git a/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java b/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
index af06bbc..c331756 100644
--- a/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
+++ b/src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java
@@ -136,7 +136,7 @@
     /**
      * 鍙戦�佸洖璁挎彁閱�
      */
-    public void sendReturnVisitReminder(Long returnVisitId, String cid, String content, Integer customerId) {
+    public void sendReturnVisitReminder(Long returnVisitId, String cid, String content, Long customerId) {
         String targetPath = "pages/cooperativeOffice/customerManage/detail?customerId=" + customerId;
         sendRoutingPush(returnVisitId, cid, "瀹㈡埛鍥炶鎻愰啋", content, targetPath, false);
     }
diff --git a/src/main/resources/mapper/basic/CustomerMapper.xml b/src/main/resources/mapper/basic/CustomerMapper.xml
index 3b42238..1e7df5c 100644
--- a/src/main/resources/mapper/basic/CustomerMapper.xml
+++ b/src/main/resources/mapper/basic/CustomerMapper.xml
@@ -12,10 +12,10 @@
         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.delete_flag = 0
-        and cpp2.bound_id != c.usage_user
+        from customer_user cu
+        left join sys_user u2 on cu.user_id = u2.user_id
+        where cu.customer_id = c.id
+        and cu.user_id != c.usage_user
         ) as together_user_names
         from customer c
         left join sys_user u on c.usage_user = u.user_id
@@ -26,8 +26,16 @@
             <if test="c.customerType != null and c.customerType != ''">
                 and customer_type = #{c.customerType}
             </if>
+            <!-- 绉佹捣鏌ヨ锛歵ype = 0锛堢娴峰鎴凤級鎴栬�� type = 1锛堝叕娴峰鎴凤級涓斿凡琚垎閰� -->
+            <if test="c.type != null and c.type == 0">
+                and type = #{c.type} or (type = 1 and is_assigned = 1)
+            </if>
+            <!-- 鍏捣鏌ヨ锛歵ype = 1锛堝叕娴峰鎴凤級-->
+            <if test="c.type != null and c.type == 1">
+                and type = #{c.type}
+            </if>
         </where>
     </select>
 
 
-</mapper>
+</mapper>
\ No newline at end of file

--
Gitblit v1.9.3