Source/UBCS/ubcs-service/ubcs-code/src/main/java/com/vci/ubcs/code/service/impl/MdmCountServiceImpl.java
@@ -4,15 +4,27 @@
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.vci.ubcs.code.entity.CodeClassify;
import com.vci.ubcs.code.entity.MdmCount;
import com.vci.ubcs.code.mapper.CommonsMapper;
import com.vci.ubcs.code.service.ICodeClassifyService;
import com.vci.ubcs.code.service.IMdmCountService;
import com.vci.ubcs.starter.web.util.VciBaseUtil;
import com.vci.ubcs.system.entity.MdmCountConfig;
import com.vci.ubcs.system.entity.Menu;
import com.vci.ubcs.system.feign.ISysClient;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
import static com.vci.ubcs.starter.web.util.VciBaseUtil.getTableName;
/**
 * 主数据统计服务
@@ -32,18 +44,111 @@
   @Resource
   private ICodeClassifyService codeClassifyService;
   @Resource
   private CommonsMapper commonsMapper;
   /**
    * 查询主数据总数
    * @param userId
    * @return
    * @throws ServiceException
    */
   @Override
   public List<MdmCount> getMdmCounts() {
      // 1、需要先查询出分类下顶级节点有哪些主数据,拿到业务类型名称
   public List<MdmCount> getMdmCounts(String userId) throws ServiceException{
      if(Func.isBlank(userId) && Func.isBlank(AuthUtil.getUserId().toString())){
         throw new ServiceException("必传参数用户id不能为空");
      }
      /** 1、先查询出各分类顶层节点有哪些主数据,拿到绑定的业务类型名称,相当于拿到主数据表名
         顶层节点的btmtypeid(2024年1月31日的时候改成了用分类的id)去查询对应的菜单表的code字段
          ,查询出主数据管理下面有哪些主数据的
         但是为了减少查询次数,就需在查询是使用id字段进行排序
       */
      LambdaQueryWrapper<CodeClassify> wrapper = Wrappers.<CodeClassify>query()
         .lambda()
         .isNull(CodeClassify::getParentCodeClassifyOid).select(CodeClassify::getBtmTypeId);
      Map<String, Object> map = codeClassifyService.getMap(wrapper);
      // 2、然后需要查询出菜单路由和图标
         .isNull(CodeClassify::getParentCodeClassifyOid)/*顶层节点*/
         .orderByAsc(CodeClassify::getId);
      // 加上租户查询条件
      if(!VciBaseUtil.checkAdminTenant()){
         wrapper.eq(CodeClassify::getTenantId,AuthUtil.getTenantId());
      }
      List<CodeClassify> codeClassifies = codeClassifyService.list(wrapper);
      // List<String> btmTypeIds = codeClassifies.stream().map(CodeClassify::getBtmTypeId).collect(Collectors.toList());
      List<String> classifyIds = codeClassifies.stream().map(CodeClassify::getId).collect(Collectors.toList());
      // 2、然后feign调用需要查询出菜单路由和图标
      R<List<Menu>> menuList = sysClient.getMenuByCodes(classifyIds,Func.toLong(userId));
      if(!menuList.isSuccess()){
         throw new ServiceException("获取主数据统计时,主数据菜单查询失败,原因:"+menuList.getMsg());
      }
      List<MdmCount> mdmCountList = new ArrayList<>();
      // 3、查询当前登录的用户配置了那些主数据统计项
      R<MdmCountConfig> mdmCountConfig = sysClient.getMdmCountConfig(Func.isBlank(userId) ? AuthUtil.getUserId().toString():userId);
      if(!mdmCountConfig.isSuccess()){
         throw new ServiceException("获取主数据统计项配置时出现错误,原因:"+mdmCountConfig.getMsg());
      }
      List<String> mdmNames = null;
      //首页配置显示少于5个就默认显示前五个
      if(Func.isBlank(mdmCountConfig.getData().getMdmName())){
         AtomicInteger count = new AtomicInteger();
         mdmNames = menuList.getData().stream().map(item->{
            if(count.getAndIncrement() <5){
               return item.getCode();
            }
            return null;
         }).collect(Collectors.toList());
      }else {
         mdmNames = Arrays.stream(mdmCountConfig.getData().getMdmName().split(",")).collect(Collectors.toList());
      }
      final List<String> mdmNamesFinal = mdmNames;
      /* 4、获取表名,当前未获取到表名,菜单的code值对应了分类的id,
         未对应业务类型的id,所以需要通过菜单的id筛选出配置并且在使用的主数据分类,
         然后通过分类信息查询到业务类型id,在通过业务类型接口查询出表名(这一步可以先省略因为分类上关联的业务类型id也可以拼接出表名)
      */
      // 获取分类上的业务类型的id
      Map<String, String> btmTypeIdMaps = menuList.getData().stream()
      .filter(menu -> codeClassifies.stream()
         .anyMatch(codeClassify -> codeClassify.getId().equals(menu.getCode()))
      ).collect(Collectors.toMap(
         Menu::getCode,
         menu -> codeClassifies.stream()
            .filter(codeClassify -> codeClassify.getId().equals(menu.getCode()))
            .findFirst()
            .map(CodeClassify::getBtmTypeId)
            .orElse(null)
      ));
      // 3、然后设置进
      // 5、然后set进对象中
      menuList.getData().stream().forEach(item->{
         Integer isDefault = mdmNamesFinal.contains(item.getCode()) ? 1:0;
         MdmCount mdmCount = new MdmCount(
            item.getName(),
            getCountByTableName(btmTypeIdMaps.get(item.getCode())), /*查询主数据总数*/
            item.getPath(),
            item.getSource(),
            item.getCode(),
            isDefault
         );
         mdmCountList.add(mdmCount);
      });
      return mdmCountList;
   }
      return null;
   /**
    * 拼接表名查询总数
    * @param tableName
    * @return
    */
   private String getCountByTableName(String tableName){
      String count = "0";
      if(Func.isBlank(tableName)){
         return count;
      }
      String sql = "SELECT COUNT(*) FROM " + getTableName(tableName,true) +";";
      try {
         count = commonsMapper.queryCountStringBySql(sql);
      }catch (Exception e){
         throw new ServiceException("主数据总数查询失败,原因:"+e.getCause());
      }
      return count;
   }
}