huminmin
9 天以前 c383c8ca7053005ffa3ee58efd89956fbf52c9ea
重构客户档案
已添加3个文件
已修改11个文件
204 ■■■■■ 文件已修改
doc/create_table_customer_user.sql 10 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/controller/CustomerController.java 19 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/dto/CustomerDto.java 1 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/Customer.java 5 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java 2 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/pojo/CustomerUser.java 43 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/ICustomerService.java 7 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerReturnVisitServiceImpl.java 6 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java 75 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/task/ReturnVisitReminderTask.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/basic/vo/CustomerVo.java 14 ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/java/com/ruoyi/project/system/service/impl/UnipushService.java 2 ●●● 补丁 | 查看 | 原始文档 | blame | 历史
src/main/resources/mapper/basic/CustomerMapper.xml 16 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
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'
);
src/main/java/com/ruoyi/basic/controller/CustomerController.java
@@ -121,4 +121,23 @@
    }
    /**
     * åˆ†é…å®¢æˆ·
     */
    @Log(title = "客户档案", businessType = BusinessType.OTHER)
    @PostMapping("/assignCustomer")
    public AjaxResult assignCustomer(@RequestBody CustomerDto customer) {
        customerService.assignCustomer(customer);
        return AjaxResult.success();
    }
    /**
     * å›žæ”¶å®¢æˆ·
     */
    @Log(title = "客户档案", businessType = BusinessType.OTHER)
    @PostMapping("/recycleCustomer")
    public AjaxResult recycleCustomer(@RequestBody CustomerDto customer) {
        customerService.recycleCustomer(customer);
        return AjaxResult.success();
    }
}
src/main/java/com/ruoyi/basic/dto/CustomerDto.java
@@ -24,5 +24,4 @@
    private String usageUserName;
    private String togetherUserNames;
}
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;
}
src/main/java/com/ruoyi/basic/pojo/CustomerFollowUp.java
@@ -39,6 +39,8 @@
     */
    private Long customerPrivatePoolId;
    private Long customerId;
    /**
     * è·Ÿè¿›æ–¹å¼
     */
src/main/java/com/ruoyi/basic/pojo/CustomerReturnVisit.java
@@ -38,6 +38,8 @@
     */
    private Integer customerPrivatePoolId;
    private Long customerId;
    /**
     * æé†’开关 (0:关闭, 1:开启)
     */
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;
}
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 å®¢æˆ·æ¡£æ¡ˆä¸»é”®
     * @return å®¢æˆ·è¯¦æƒ…DTO
     */
    Customer selectCustomerDetailById(Long id);
    CustomerVo selectCustomerDetailById(Long id);
    /**
     * æŸ¥è¯¢å®¢æˆ·æ¡£æ¡ˆåˆ—表
@@ -80,4 +81,8 @@
    AjaxResult importData(MultipartFile file);
    IPage<CustomerDto> selectCustomerList(Page<CustomerDto> page, CustomerDto customer);
    void assignCustomer(CustomerDto customer);
    void recycleCustomer(CustomerDto customer);
}
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) {
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("客户档案下有销售合同,请先删除销售合同");
        }
        List<CustomerPrivatePool> customerPrivatePools = customerPrivatePoolMapper.selectList(new QueryWrapper<CustomerPrivatePool>().lambda().in(CustomerPrivatePool::getCustomerId, idList));
        if (!customerPrivatePools.isEmpty()) {
            throw new RuntimeException("客户档案下有客户私海,请先收回私海数据");
        // æŸ¥è¯¢æ˜¯å¦æœ‰å·²åˆ†é…çš„公海客户
        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("客户档案下有已分配的公海客户,请先收回");
        }
        //  åˆ é™¤å®¢æˆ·çš„同时也需要删除对应的客户跟随、附件和回访提醒
        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);
        }
    }
    /**
     * ä¸‹åˆ’线命名转驼峰命名
     */
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);
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;
}
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);
    }
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,6 +26,14 @@
            <if test="c.customerType != null and c.customerType != ''">
                and customer_type = #{c.customerType}
            </if>
            <!-- ç§æµ·æŸ¥è¯¢ï¼štype = 0(私海客户)或者 type = 1(公海客户)且已被分配 -->
            <if test="c.type != null and c.type == 0">
                and type = #{c.type} or (type = 1 and is_assigned = 1)
            </if>
            <!-- å…¬æµ·æŸ¥è¯¢ï¼štype = 1(公海客户)-->
            <if test="c.type != null and c.type == 1">
                and type = #{c.type}
            </if>
        </where>
    </select>