|
|
@@ -2,12 +2,14 @@ package com.storlead.trade.service.impl;
|
|
|
|
|
|
import com.baomidou.dynamic.datasource.annotation.DS;
|
|
|
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.extension.plugins.pagination.Page;
|
|
|
import com.storlead.framework.common.constant.CommonConstant;
|
|
|
import com.storlead.framework.common.constant.DSConstants;
|
|
|
import com.storlead.framework.common.result.Result;
|
|
|
import com.storlead.framework.mybatis.service.impl.MyBaseServiceImpl;
|
|
|
+import com.storlead.trade.dto.SysDictDetailResponseDTO;
|
|
|
import com.storlead.trade.dto.CustomerDTO;
|
|
|
import com.storlead.trade.entity.CustomerCompanyEntity;
|
|
|
import com.storlead.trade.entity.CustomerEntity;
|
|
|
@@ -18,6 +20,8 @@ import com.storlead.trade.service.CustomerCompanyTradeService;
|
|
|
import com.storlead.trade.service.CustomerTradeService;
|
|
|
import com.storlead.trade.service.CustomerAnalysisResultEntityService;
|
|
|
import com.storlead.trade.service.LiaisonTradeService;
|
|
|
+import com.storlead.trade.service.SysDictService;
|
|
|
+import com.storlead.trade.vo.CustomerSourceDistributionVO;
|
|
|
import com.storlead.trade.vo.CustomerVO;
|
|
|
import org.springframework.beans.BeanUtils;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
@@ -27,13 +31,16 @@ import org.springframework.util.ObjectUtils;
|
|
|
import org.springframework.util.StringUtils;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
+import java.util.HashMap;
|
|
|
import java.util.HashSet;
|
|
|
import java.util.List;
|
|
|
import java.util.Map;
|
|
|
import java.util.Objects;
|
|
|
import java.util.Set;
|
|
|
import java.util.stream.Collectors;
|
|
|
+import lombok.extern.slf4j.Slf4j;
|
|
|
|
|
|
+@Slf4j
|
|
|
@Service
|
|
|
@DS(DSConstants.DATASOURCE_TRADE)
|
|
|
public class CustomerTradeServiceImpl
|
|
|
@@ -43,14 +50,17 @@ public class CustomerTradeServiceImpl
|
|
|
private final CustomerCompanyTradeService customerCompanyTradeService;
|
|
|
private final LiaisonTradeService liaisonTradeService;
|
|
|
private final CustomerAnalysisResultEntityService customerAnalysisResultEntityService;
|
|
|
+ private final SysDictService sysDictService;
|
|
|
|
|
|
public CustomerTradeServiceImpl(
|
|
|
CustomerCompanyTradeService customerCompanyTradeService,
|
|
|
LiaisonTradeService liaisonTradeService,
|
|
|
- CustomerAnalysisResultEntityService customerAnalysisResultEntityService) {
|
|
|
+ CustomerAnalysisResultEntityService customerAnalysisResultEntityService,
|
|
|
+ SysDictService sysDictService) {
|
|
|
this.customerCompanyTradeService = customerCompanyTradeService;
|
|
|
this.liaisonTradeService = liaisonTradeService;
|
|
|
this.customerAnalysisResultEntityService = customerAnalysisResultEntityService;
|
|
|
+ this.sysDictService = sysDictService;
|
|
|
}
|
|
|
|
|
|
@Override
|
|
|
@@ -308,4 +318,75 @@ public class CustomerTradeServiceImpl
|
|
|
}
|
|
|
return Result.ok();
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public List<CustomerSourceDistributionVO> getSourceDistribution(List<Long> idList) {
|
|
|
+ // Step1: 按 customer_source_dict_value 分组统计
|
|
|
+ QueryWrapper<CustomerEntity> qw = new QueryWrapper<>();
|
|
|
+ qw.select("customer_source_dict_value AS source, count(*) AS cnt");
|
|
|
+ qw.eq("is_delete", CommonConstant.DEL_FLAG_0);
|
|
|
+ // 仅在 idList 非空时限定客户范围
|
|
|
+ if (!CollectionUtils.isEmpty(idList)) {
|
|
|
+ qw.in("id", idList);
|
|
|
+ }
|
|
|
+ qw.groupBy("customer_source_dict_value");
|
|
|
+ List<Map<String, Object>> rows = this.listMaps(qw);
|
|
|
+
|
|
|
+ // Step2: 计算总数
|
|
|
+ long total = 0L;
|
|
|
+ if (rows != null) {
|
|
|
+ for (Map<String, Object> r : rows) {
|
|
|
+ Object cnt = r.get("cnt");
|
|
|
+ if (cnt instanceof Number) {
|
|
|
+ total += ((Number) cnt).longValue();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Step3: sys_dict_detail 翻译 source -> label
|
|
|
+ Map<String, String> labelMap = new HashMap<>();
|
|
|
+ try {
|
|
|
+ List<SysDictDetailResponseDTO> details = sysDictService.getListByCode("customer_source");
|
|
|
+ if (!CollectionUtils.isEmpty(details)) {
|
|
|
+ for (SysDictDetailResponseDTO d : details) {
|
|
|
+ if (d != null && d.getValue() != null) {
|
|
|
+ labelMap.put(d.getValue(), d.getLabel());
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ } catch (Exception ex) {
|
|
|
+ log.warn("查询 customer_source 字典明细失败,跳过 label 翻译: {}", ex.getMessage());
|
|
|
+ }
|
|
|
+
|
|
|
+ // Step4: 组装 VO(保留 source 为 null 的桶,label 标"未分类")
|
|
|
+ List<CustomerSourceDistributionVO> result = new ArrayList<>();
|
|
|
+ if (rows != null) {
|
|
|
+ for (Map<String, Object> r : rows) {
|
|
|
+ Object srcObj = r.get("source");
|
|
|
+ Object cntObj = r.get("cnt");
|
|
|
+ String source = srcObj == null ? null : srcObj.toString();
|
|
|
+ long cnt = cntObj instanceof Number ? ((Number) cntObj).longValue() : 0L;
|
|
|
+ double ratio = total > 0 ? Math.round(cnt * 10000.0 / total) / 100.0 : 0.0;
|
|
|
+
|
|
|
+ CustomerSourceDistributionVO vo = new CustomerSourceDistributionVO();
|
|
|
+ vo.setSource(source);
|
|
|
+ vo.setCount(cnt);
|
|
|
+ vo.setRatio(ratio);
|
|
|
+ if (source == null || source.isEmpty()) {
|
|
|
+ vo.setSourceLabel("未分类");
|
|
|
+ } else {
|
|
|
+ vo.setSourceLabel(labelMap.getOrDefault(source, source));
|
|
|
+ }
|
|
|
+ result.add(vo);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Step5: 按 count 降序
|
|
|
+ result.sort((a, b) -> {
|
|
|
+ long ac = a.getCount() == null ? 0L : a.getCount();
|
|
|
+ long bc = b.getCount() == null ? 0L : b.getCount();
|
|
|
+ return Long.compare(bc, ac);
|
|
|
+ });
|
|
|
+ return result;
|
|
|
+ }
|
|
|
}
|