src/main/java/com/ruoyi/basic/service/impl/CustomerServiceImpl.java
@@ -24,13 +24,16 @@
import com.ruoyi.procurementrecord.mapper.ReturnManagementMapper;
import com.ruoyi.procurementrecord.pojo.ReturnManagement;
import com.ruoyi.sales.mapper.SalesLedgerMapper;
import com.ruoyi.sales.mapper.SalesQuotationMapper;
import com.ruoyi.sales.pojo.SalesLedger;
import com.ruoyi.sales.pojo.SalesQuotation;
import com.ruoyi.sales.vo.CustomerTransactionsDetailsVo;
import com.ruoyi.sales.vo.CustomerTransactionsVo;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
@@ -54,6 +57,8 @@
    @Autowired
    private SalesLedgerMapper salesLedgerMapper;
    @Autowired
    private SalesQuotationMapper salesQuotationMapper;
    @Autowired
    private ReturnManagementMapper returnManagementMapper;
    @Autowired
    private CustomerMapper customerMapper;
@@ -66,6 +71,8 @@
    private CustomerReturnVisitService customerReturnVisitService;
    @Autowired
    private CustomerUserService customerUserService;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    /**
     * 查询客户档案
@@ -88,6 +95,13 @@
    public CustomerVo selectCustomerDetailById(Long id) {
        CustomerVo customerVo = new CustomerVo();
        BeanUtils.copyProperties(this.getById(id), customerVo);
        // 回显绑定的登录账号
        CustomerUser binding = customerUserService.getOne(new LambdaQueryWrapper<CustomerUser>()
                .eq(CustomerUser::getCustomerId, id).last("limit 1"), false);
        if (binding != null) {
            customerVo.setBindUserId(binding.getUserId());
        }
        // 查询跟进记录
        List<CustomerFollowUp> followUpList = customerFollowUpService.list(
@@ -125,7 +139,8 @@
    @Override
    public IPage<CustomerVo> selectCustomerList(Page<CustomerDto> page, CustomerDto customer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long loginUserId = loginUser.getUserId();
        // 超级管理员不受客户领用/共享范围限制,可查看全部客户
        Long loginUserId = isSuperAdmin(loginUser) ? null : loginUser.getUserId();
        IPage<CustomerVo> customerPage = customerMapper.listPage(page, customer, loginUserId);
        List<CustomerVo> records = customerPage.getRecords();
@@ -191,11 +206,14 @@
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertCustomer(Customer customer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long tenantId = loginUser.getTenantId();
        customer.setTenantId(tenantId);
        return customerMapper.insert(customer);
        int rows = customerMapper.insert(customer);
        saveCustomerBinding(customer.getId(), customer.getBindUserId());
        return rows;
    }
    /**
@@ -205,11 +223,38 @@
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateCustomer(Customer customer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long tenantId = loginUser.getTenantId();
        customer.setTenantId(tenantId);
        return customerMapper.updateById(customer);
        int rows = customerMapper.updateById(customer);
        saveCustomerBinding(customer.getId(), customer.getBindUserId());
        return rows;
    }
    /**
     * 保存客户与登录账号的一对一绑定关系
     */
    private void saveCustomerBinding(Long customerId, Long bindUserId) {
        if (customerId == null) {
            return;
        }
        customerUserService.remove(new LambdaQueryWrapper<CustomerUser>()
                .eq(CustomerUser::getCustomerId, customerId));
        if (bindUserId == null) {
            return;
        }
        // 一个登录账号只能绑定一个客户
        customerUserService.remove(new LambdaQueryWrapper<CustomerUser>()
                .eq(CustomerUser::getUserId, bindUserId));
        CustomerUser binding = new CustomerUser();
        binding.setCustomerId(customerId);
        binding.setUserId(bindUserId);
        customerUserService.save(binding);
        // 绑定账号自动授予“客户”角色,使其登录后只能访问客户门户
        jdbcTemplate.update("INSERT IGNORE INTO sys_user_role (user_id, role_id) "
                + "SELECT ?, role_id FROM sys_role WHERE role_key = 'customer' AND del_flag = '0'", bindUserId);
    }
    /**
@@ -233,6 +278,13 @@
        if (!returnManagements.isEmpty()) {
            throw new RuntimeException("客户档案下有销售退货,请先删除销售退货");
        }
        // 检查是否有销售报价关联
        List<SalesQuotation> salesQuotations = salesQuotationMapper.selectList(new QueryWrapper<SalesQuotation>().lambda().in(SalesQuotation::getCustomerId, idList));
        if (!salesQuotations.isEmpty()) {
            throw new RuntimeException("客户档案下有销售报价,请先删除销售报价");
        }
        // 查询是否有已分配的公海客户
        List<Customer> assignedPools = customerMapper.selectList(
                new QueryWrapper<Customer>().lambda()
@@ -268,8 +320,14 @@
    @Override
    public List<CustomerVo> selectCustomerLists(CustomerDto customer) {
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long loginUserId = loginUser.getUserId();
        // 超级管理员不受客户领用/共享范围限制,可导出全部客户
        Long loginUserId = isSuperAdmin(loginUser) ? null : loginUser.getUserId();
        return customerMapper.list(customer, loginUserId);
    }
    /** 超级管理员:不受客户领用/共享范围限制 */
    private boolean isSuperAdmin(LoginUser loginUser) {
        return loginUser != null && loginUser.getUser() != null && loginUser.getUser().isAdmin();
    }
    @Override
@@ -298,18 +356,26 @@
    @Override
    public List<Map<String, Object>> customerList(Customer customer) {
        LambdaQueryWrapper<Customer> queryWrapper = Wrappers.lambdaQuery();
        queryWrapper.select(Customer::getId, Customer::getCustomerName, Customer::getTaxpayerIdentificationNumber);
        LoginUser loginUser = SecurityUtils.getLoginUser();
        Long loginUserId = loginUser.getUserId();
        CustomerDto query = new CustomerDto();
        if (customer != null) {
            BeanUtils.copyProperties(customer, query);
        }
        // 获取原始查询结果
        List<Map<String, Object>> result = customerMapper.selectMaps(queryWrapper);
        // 复用客户列表的可见性规则,避免把别人的私海客户暴露给当前账号
        List<CustomerVo> visibleCustomers = customerMapper.list(query, loginUserId);
        if (CollectionUtils.isEmpty(visibleCustomers)) {
            return Collections.emptyList();
        }
        // 将下划线命名转换为驼峰命名
        return result.stream().map(map -> map.entrySet().stream()
                .collect(Collectors.toMap(
                        entry -> underlineToCamel(entry.getKey()),
                        Map.Entry::getValue))
        ).collect(Collectors.toList());
        return visibleCustomers.stream().map(item -> {
            Map<String, Object> map = new LinkedHashMap<>();
            map.put("id", item.getId());
            map.put("customerName", item.getCustomerName());
            map.put("taxpayerIdentificationNumber", item.getTaxpayerIdentificationNumber());
            return map;
        }).collect(Collectors.toList());
    }
    // 分配公海客户给私海
@@ -330,6 +396,7 @@
    public void recycleCustomer(CustomerDto customerDto) {
        Customer customer = customerMapper.selectById(customerDto.getId());
        if (customer.getType() == 1 && customer.getIsAssigned() == 1) {  // 公海且已分配
            validatePublicSeaRecyclePermission(customer.getId());
            customer.setIsAssigned(0);
            customer.setUsageStatus(0L);
            customer.setUsageUser(0L);
@@ -392,6 +459,28 @@
        return this.updateById(customer);
    }
    private void validatePublicSeaRecyclePermission(Long customerId) {
        if (hasSalesModuleReference(customerId)) {
            throw new RuntimeException("已领用并且被销售模块引用的公海客户不能回收");
        }
    }
    private boolean hasSalesModuleReference(Long customerId) {
        Long salesLedgerCount = salesLedgerMapper.selectCount(new QueryWrapper<SalesLedger>().lambda()
                .eq(SalesLedger::getCustomerId, customerId));
        if (salesLedgerCount != null && salesLedgerCount > 0) {
            return true;
        }
        Long salesQuotationCount = salesQuotationMapper.selectCount(new QueryWrapper<SalesQuotation>().lambda()
                .eq(SalesQuotation::getCustomerId, customerId));
        if (salesQuotationCount != null && salesQuotationCount > 0) {
            return true;
        }
        Long returnManagementCount = returnManagementMapper.selectCount(new QueryWrapper<ReturnManagement>().lambda()
                .eq(ReturnManagement::getCustomerId, customerId));
        return returnManagementCount != null && returnManagementCount > 0;
    }
    @Override
    public IPage<CustomerTransactionsVo> customewTransactions(Page page, String customerName) {
        return customerMapper.customewTransactions(page, customerName);