|
|
@@ -1,29 +1,40 @@
|
|
|
package org.dromara.customer.service.impl;
|
|
|
|
|
|
-import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
-import org.dromara.common.core.utils.MapstructUtils;
|
|
|
-import org.dromara.common.core.utils.StringUtils;
|
|
|
-import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
-import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
-import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import cn.hutool.core.collection.CollUtil;
|
|
|
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
|
|
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
|
|
import lombok.RequiredArgsConstructor;
|
|
|
import lombok.extern.slf4j.Slf4j;
|
|
|
-import org.dromara.customer.domain.CustomerInfo;
|
|
|
-import org.dromara.customer.domain.SupplierInfo;
|
|
|
-import org.dromara.customer.domain.vo.CustomerInfoVo;
|
|
|
-import org.springframework.stereotype.Service;
|
|
|
-import org.dromara.customer.domain.bo.PartnerInfoBo;
|
|
|
-import org.dromara.customer.domain.vo.PartnerInfoVo;
|
|
|
+import org.apache.dubbo.config.annotation.DubboReference;
|
|
|
+import org.dromara.common.core.domain.R;
|
|
|
+import org.dromara.common.core.utils.MapstructUtils;
|
|
|
+import org.dromara.common.core.utils.StringUtils;
|
|
|
+import org.dromara.common.mybatis.core.page.PageQuery;
|
|
|
+import org.dromara.common.mybatis.core.page.TableDataInfo;
|
|
|
+import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
+import org.dromara.customer.domain.PartnerContacts;
|
|
|
+import org.dromara.customer.domain.PartnerContract;
|
|
|
import org.dromara.customer.domain.PartnerInfo;
|
|
|
import org.dromara.customer.domain.PartnerUser;
|
|
|
+import org.dromara.customer.domain.bo.PartnerInfoBo;
|
|
|
+import org.dromara.customer.domain.vo.PartnerInfoVo;
|
|
|
+import org.dromara.customer.domain.vo.PartnerManageIndexDataVo;
|
|
|
+import org.dromara.customer.mapper.PartnerContactsMapper;
|
|
|
+import org.dromara.customer.mapper.PartnerContractMapper;
|
|
|
import org.dromara.customer.mapper.PartnerInfoMapper;
|
|
|
import org.dromara.customer.mapper.PartnerUserMapper;
|
|
|
import org.dromara.customer.service.IPartnerInfoService;
|
|
|
-import org.dromara.common.satoken.utils.LoginHelper;
|
|
|
+import org.dromara.system.api.RemoteDictService;
|
|
|
+import org.dromara.system.api.domain.vo.RemoteDictDataVo;
|
|
|
+import org.springframework.stereotype.Service;
|
|
|
|
|
|
+import java.time.LocalDate;
|
|
|
+import java.time.ZoneId;
|
|
|
+import java.time.format.DateTimeFormatter;
|
|
|
import java.util.*;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
/**
|
|
|
* 伙伴商基本信息Service业务层处理
|
|
|
@@ -38,6 +49,11 @@ public class PartnerInfoServiceImpl extends ServiceImpl<PartnerInfoMapper, Partn
|
|
|
|
|
|
private final PartnerInfoMapper baseMapper;
|
|
|
private final PartnerUserMapper partnerUserMapper;
|
|
|
+ private final PartnerContractMapper partnerContractMapper;
|
|
|
+ private final PartnerContactsMapper partnerContactsMapper;
|
|
|
+
|
|
|
+ @DubboReference
|
|
|
+ private RemoteDictService remoteDictService;
|
|
|
|
|
|
/**
|
|
|
* 查询伙伴商基本信息
|
|
|
@@ -209,7 +225,7 @@ public class PartnerInfoServiceImpl extends ServiceImpl<PartnerInfoMapper, Partn
|
|
|
private String generatePartnerNo() {
|
|
|
// 获取当前年份
|
|
|
String year = String.valueOf(java.time.LocalDate.now().getYear());
|
|
|
-
|
|
|
+
|
|
|
// 查询当年最大的编号
|
|
|
LambdaQueryWrapper<PartnerInfo> lqw = Wrappers.lambdaQuery();
|
|
|
lqw.select(PartnerInfo::getPartnerNo);
|
|
|
@@ -231,8 +247,150 @@ public class PartnerInfoServiceImpl extends ServiceImpl<PartnerInfoMapper, Partn
|
|
|
log.warn("解析伙伴商编号失败: {}", maxRecord.getPartnerNo());
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
// 格式化为 P + 年份 + 3位序号,如 P2026001
|
|
|
return String.format("P%s%03d", year, nextNum);
|
|
|
}
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public R<PartnerManageIndexDataVo> partnerManageIndexData() {
|
|
|
+ PartnerManageIndexDataVo vo = new PartnerManageIndexDataVo();
|
|
|
+ LocalDate today = LocalDate.now();
|
|
|
+
|
|
|
+ // 1. 伙伴商总数
|
|
|
+ vo.setPartnerTotal(baseMapper.selectCount(null));
|
|
|
+
|
|
|
+ // 2. 本月新增入驻
|
|
|
+ LocalDate firstDayOfMonth = today.withDayOfMonth(1);
|
|
|
+ vo.setMonthlyNew(baseMapper.selectCount(new LambdaQueryWrapper<PartnerInfo>()
|
|
|
+ .ge(PartnerInfo::getCreateTime, java.sql.Date.valueOf(firstDayOfMonth))
|
|
|
+ .lt(PartnerInfo::getCreateTime, java.sql.Date.valueOf(today.plusDays(1)))
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 3. 季度新增入驻
|
|
|
+ int quarterStartMonth = ((today.getMonthValue() - 1) / 3) * 3 + 1;
|
|
|
+ LocalDate firstDayOfQuarter = LocalDate.of(today.getYear(), quarterStartMonth, 1);
|
|
|
+ vo.setQuarterlyNew(baseMapper.selectCount(new LambdaQueryWrapper<PartnerInfo>()
|
|
|
+ .ge(PartnerInfo::getCreateTime, java.sql.Date.valueOf(firstDayOfQuarter))
|
|
|
+ .lt(PartnerInfo::getCreateTime, java.sql.Date.valueOf(today.plusDays(1)))
|
|
|
+ ));
|
|
|
+
|
|
|
+ // 4. 合作中项目数(PartnerContract中cooperationId去重)
|
|
|
+ List<PartnerContract> contracts = partnerContractMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<PartnerContract>()
|
|
|
+ .isNotNull(PartnerContract::getCooperationId)
|
|
|
+ .select(PartnerContract::getCooperationId)
|
|
|
+ );
|
|
|
+ vo.setCooperationProjectCount(contracts.stream()
|
|
|
+ .map(PartnerContract::getCooperationId)
|
|
|
+ .filter(Objects::nonNull)
|
|
|
+ .distinct()
|
|
|
+ .count());
|
|
|
+
|
|
|
+ // 5. 近半年新增伙伴商趋势
|
|
|
+ DateTimeFormatter monthFormatter = DateTimeFormatter.ofPattern("M月");
|
|
|
+ List<PartnerManageIndexDataVo.MonthTrend> monthlyTrend = new ArrayList<>();
|
|
|
+ for (int i = 5; i >= 0; i--) {
|
|
|
+ LocalDate monthStart = today.minusMonths(i).withDayOfMonth(1);
|
|
|
+ LocalDate monthEnd = monthStart.plusMonths(1);
|
|
|
+
|
|
|
+ PartnerManageIndexDataVo.MonthTrend trend = new PartnerManageIndexDataVo.MonthTrend();
|
|
|
+ trend.setMonth(monthStart.format(monthFormatter));
|
|
|
+ trend.setCount(baseMapper.selectCount(new LambdaQueryWrapper<PartnerInfo>()
|
|
|
+ .ge(PartnerInfo::getCreateTime, java.sql.Date.valueOf(monthStart))
|
|
|
+ .lt(PartnerInfo::getCreateTime, java.sql.Date.valueOf(monthEnd))
|
|
|
+ ));
|
|
|
+ monthlyTrend.add(trend);
|
|
|
+ }
|
|
|
+ vo.setMonthlyTrend(monthlyTrend);
|
|
|
+
|
|
|
+ // 6. 伙伴合作型态分布
|
|
|
+ List<PartnerInfo> allPartners = baseMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<PartnerInfo>()
|
|
|
+ .isNotNull(PartnerInfo::getPartnerCooperateType)
|
|
|
+ .select(PartnerInfo::getPartnerCooperateType)
|
|
|
+ );
|
|
|
+ Map<Long, Long> typeCountMap = allPartners.stream()
|
|
|
+ .filter(p -> p.getPartnerCooperateType() != null)
|
|
|
+ .collect(Collectors.groupingBy(PartnerInfo::getPartnerCooperateType, Collectors.counting()));
|
|
|
+
|
|
|
+ // 查询字典获取类型名称
|
|
|
+ List<RemoteDictDataVo> cooperateTypeDicts = remoteDictService.selectDictDataByType("cooperate_type");
|
|
|
+ Map<String, String> dictMap = CollUtil.emptyIfNull(cooperateTypeDicts).stream()
|
|
|
+ .collect(Collectors.toMap(RemoteDictDataVo::getDictValue, RemoteDictDataVo::getDictLabel, (k1, k2) -> k1));
|
|
|
+
|
|
|
+ List<PartnerManageIndexDataVo.TypeDistribution> typeDistributions = typeCountMap.entrySet().stream()
|
|
|
+ .map(entry -> {
|
|
|
+ PartnerManageIndexDataVo.TypeDistribution td = new PartnerManageIndexDataVo.TypeDistribution();
|
|
|
+ String typeName = dictMap.get(String.valueOf(entry.getKey()));
|
|
|
+ td.setName(typeName != null ? typeName : "未知");
|
|
|
+ td.setValue(entry.getValue());
|
|
|
+ return td;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ vo.setTypeDistribution(typeDistributions);
|
|
|
+
|
|
|
+ // 7. 最新入驻伙伴商列表(最新8条)
|
|
|
+ List<PartnerInfo> latestPartners = baseMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<PartnerInfo>()
|
|
|
+ .orderByDesc(PartnerInfo::getCreateTime)
|
|
|
+ .last("LIMIT 8")
|
|
|
+ );
|
|
|
+
|
|
|
+ if (CollUtil.isNotEmpty(latestPartners)) {
|
|
|
+ Set<Long> partnerIds = latestPartners.stream()
|
|
|
+ .map(PartnerInfo::getId)
|
|
|
+ .collect(Collectors.toSet());
|
|
|
+
|
|
|
+ // 查询联系人,优先取contactType=1,没有则取contactType=2的任意一个
|
|
|
+ List<PartnerContacts> allContacts = partnerContactsMapper.selectList(
|
|
|
+ new LambdaQueryWrapper<PartnerContacts>()
|
|
|
+ .in(PartnerContacts::getPartnerId, partnerIds)
|
|
|
+ );
|
|
|
+
|
|
|
+ Map<Long, PartnerContacts> contactMap = allContacts.stream()
|
|
|
+ .collect(Collectors.groupingBy(
|
|
|
+ PartnerContacts::getPartnerId,
|
|
|
+ Collectors.collectingAndThen(
|
|
|
+ Collectors.toList(),
|
|
|
+ list -> {
|
|
|
+ // 先找type=1
|
|
|
+ Optional<PartnerContacts> type1 = list.stream()
|
|
|
+ .filter(c -> c.getContactType() != null && c.getContactType() == 1)
|
|
|
+ .findFirst();
|
|
|
+ if (type1.isPresent()) return type1.get();
|
|
|
+ // 再找type=2
|
|
|
+ Optional<PartnerContacts> type2 = list.stream()
|
|
|
+ .filter(c -> c.getContactType() != null && c.getContactType() == 2)
|
|
|
+ .findFirst();
|
|
|
+ return type2.orElse(null);
|
|
|
+ }
|
|
|
+ )
|
|
|
+ ));
|
|
|
+
|
|
|
+ DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
|
|
+ List<PartnerManageIndexDataVo.LatestPartner> partnerList = latestPartners.stream().map(p -> {
|
|
|
+ PartnerManageIndexDataVo.LatestPartner lp = new PartnerManageIndexDataVo.LatestPartner();
|
|
|
+ lp.setCompanyName(p.getPartnerName());
|
|
|
+ lp.setPartnerCooperateType(p.getPartnerCooperateType());
|
|
|
+
|
|
|
+ PartnerContacts contact = contactMap.get(p.getId());
|
|
|
+ if (contact != null) {
|
|
|
+ lp.setContact(contact.getName());
|
|
|
+ lp.setPhone(contact.getPhone());
|
|
|
+ }
|
|
|
+
|
|
|
+ if (p.getCreateTime() != null) {
|
|
|
+ lp.setJoinTime(p.getCreateTime().toInstant()
|
|
|
+ .atZone(ZoneId.systemDefault())
|
|
|
+ .toLocalDateTime().format(dateTimeFormatter));
|
|
|
+ }
|
|
|
+ return lp;
|
|
|
+ }).collect(Collectors.toList());
|
|
|
+ vo.setLatestPartners(partnerList);
|
|
|
+ } else {
|
|
|
+ vo.setLatestPartners(Collections.emptyList());
|
|
|
+ }
|
|
|
+
|
|
|
+ return R.ok(vo);
|
|
|
+ }
|
|
|
}
|