Ver Fonte

Merge branch 'ljy'

Lijingyang há 1 mês atrás
pai
commit
e2cc865924
21 ficheiros alterados com 881 adições e 19 exclusões
  1. 41 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteSupplierInfoService.java
  2. 21 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/SupplierAreaDTO.java
  3. 161 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/SupplierAuthorizeDTO.java
  4. 164 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteSupplierInfoServiceImpl.java
  5. 6 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierAuthorizeService.java
  6. 4 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierInfoService.java
  7. 2 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplyAreaService.java
  8. 48 7
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAuthorizeServiceImpl.java
  9. 33 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java
  10. 9 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplyAreaServiceImpl.java
  11. 3 3
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePullController.java
  12. 33 0
      ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/ContractSupplyJobTask.java
  13. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ContractProductController.java
  14. 4 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBrandController.java
  15. 22 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ContractProductBo.java
  16. 88 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ContractProductVo.java
  17. 4 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBrandVo.java
  18. 2 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IContractProductService.java
  19. 217 3
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ContractProductServiceImpl.java
  20. 0 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
  21. 10 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBrandServiceImpl.java

+ 41 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteSupplierInfoService.java

@@ -1,5 +1,9 @@
 package org.dromara.customer.api;
 
+import org.dromara.customer.api.domain.dto.SupplierAreaDTO;
+import org.dromara.customer.api.domain.dto.SupplierAuthorizeDTO;
+
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
@@ -17,4 +21,41 @@ public interface RemoteSupplierInfoService {
      * 根据ids查询供应商名称
      */
     Map<Long, String> selectSupplierNameByIds(Set<Long> ids);
+
+    List<SupplierAuthorizeDTO> getSupplierAuthorizeList(Long brandId);
+
+    /**
+     * 根据企业名称获取供应商id集合
+     * @param enterpriseName
+     * @return
+     */
+    List<Long> getSupplierIds(String enterpriseName);
+
+    /**
+     * 根据供应区域获取供应商id集合
+     * @param areaname
+     * @param level
+     * @return
+     */
+    List<Long> getSupplierIdsBySupplyArea(String areaname,String level);
+
+    /**
+     * 根据供应商id获取合同id集合
+     * @param SupplierID
+     * @return
+     */
+    List<Long> getContractIdBySupplySupplierID(Set<Long> SupplierID);
+
+
+    Map<Long,Long> contractToSupplierMap(List<Long> contractSupplyIds);
+
+    /**
+     * 根据ids查询供应商名称
+     */
+    Map<Long, String> selectEnterpriseNameByIds(List<Long> ids);
+
+
+    Map<Long, SupplierAreaDTO> selectSupplierInfoByContractIds(List<Long> contractSupplyIds);
+
+    int updateExpiredAuthorizedStatus();
 }

+ 21 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/SupplierAreaDTO.java

@@ -0,0 +1,21 @@
+package org.dromara.customer.api.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+
+/**
+ * author
+ * 时间:2026/3/12,15:13
+ */
+@Data
+public class SupplierAreaDTO implements Serializable {
+    private String enterpriseName;
+
+    private String provinceName;
+
+    private String cityName;
+
+    private Date endTime;
+}

+ 161 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/dto/SupplierAuthorizeDTO.java

@@ -0,0 +1,161 @@
+package org.dromara.customer.api.domain.dto;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * author
+ * 时间:2026/3/11,9:56
+ */
+@Data
+public class SupplierAuthorizeDTO implements Serializable {
+    private Long id;
+
+    /**
+     * 类目ID 三级
+     */
+    private Long categoryId;
+
+    private Long brandId;
+
+    /**
+     * 供应商编号
+     */
+    private String supplierNo;
+
+    /**
+     * 供应商ID
+     */
+    private Long supplierId;
+
+    /**
+     * 供应商名称
+     */
+    private String supplierName;
+
+
+    /**
+     * 供货类目
+     */
+    private String supplyProCate;
+
+    /**
+     * 可供货品牌
+     */
+    private String supplyBrand;
+
+    /**
+     * 授权单编号
+     */
+    private String authorizeNo;
+
+    /**
+     * 有授权品牌
+     */
+    private String authBrand;
+
+    /**
+     * 品牌编号
+     */
+    private String brandNo;
+
+    /**
+     * 品牌名称(中文)
+     */
+    private String brandName;
+
+    /**
+     * 品牌英文名称
+     */
+    private String brandEnglishName;
+
+    /**
+     * 品牌LOGO图片地址
+     */
+    private String brandLogo;
+
+    /**
+     * 授权类型(如独家/非独家)
+     */
+    private String authorizeType;
+
+    /**
+     * 授权品类(多个品类用分隔符区分)
+     */
+    private String authorizationCategory;
+
+    /**
+     * 品牌授权方(授权出具主体)
+     */
+    private String brandLicensor;
+
+    /**
+     * 授权关系文件存储地址
+     */
+    private String authorizationRelationshipFile;
+
+    /**
+     * 授权开始时间
+     */
+    private Date authorizationStartTime;
+
+    /**
+     * 授权结束时间
+     */
+    private Date authorizationEndTime;
+
+    /**
+     * 授权区域(如中国大陆/全球等)
+     */
+    private String authorizedArea;
+
+    /**
+     * 品牌持有类型(如自有/代理)
+     */
+    private String brandHoldType;
+
+    /**
+     * 授权层级(如一级/二级授权)
+     */
+    private String authorizeLevel;
+
+    /**
+     * 授权审核状态(0待审核/1已通过/2已驳回)
+     */
+    private String authorizedStatus;
+
+    /**
+     * 授权关系文件原文件名
+     */
+    private String authorizationRelationshipFileName;
+
+    /**
+     * 品牌注册人
+     */
+    private String brandRegistrant;
+
+    /**
+     * 审核反馈意见
+     */
+    private String reviewFeedback;
+
+    /**
+     * 供应区域(省)
+     */
+    private String province;
+
+    /**
+     * 供应区域(市)
+     */
+    private String city;
+
+    /**
+     * 一级,二级,三级品目名称 oneLevelName twoLevelName threeLevelName
+     */
+    Map<String, String> categorysMap;
+
+}

+ 164 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteSupplierInfoServiceImpl.java

@@ -1,14 +1,25 @@
 package org.dromara.customer.dubbo;
 
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.customer.api.RemoteSupplierInfoService;
+import org.dromara.customer.api.domain.dto.SupplierAreaDTO;
+import org.dromara.customer.api.domain.dto.SupplierAuthorizeDTO;
+import org.dromara.customer.domain.ContractSupply;
+import org.dromara.customer.domain.SupplyArea;
+import org.dromara.customer.domain.vo.SupplyAreaVo;
+import org.dromara.customer.service.IContractSupplyService;
+import org.dromara.customer.service.ISupplierAuthorizeService;
 import org.dromara.customer.service.ISupplierInfoService;
+import org.dromara.customer.service.ISupplyAreaService;
 import org.springframework.stereotype.Service;
 
-import java.util.Map;
-import java.util.Set;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * author
@@ -22,6 +33,12 @@ public class RemoteSupplierInfoServiceImpl implements RemoteSupplierInfoService
 
     private final ISupplierInfoService supplierInfoService;
 
+    private final ISupplierAuthorizeService supplierAuthorizeService;
+
+    private final ISupplyAreaService supplyAreaService;
+
+    private final IContractSupplyService contractSupplyService;
+
     @Override
     public int updateIsDisable() {
         return supplierInfoService.updateIsDisable();
@@ -31,4 +48,149 @@ public class RemoteSupplierInfoServiceImpl implements RemoteSupplierInfoService
     public Map<Long, String> selectSupplierNameByIds(Set<Long> ids) {
         return supplierInfoService.selectSupplierNameByIds(ids);
     }
+
+    @Override
+    public List<SupplierAuthorizeDTO> getSupplierAuthorizeList(Long brandId) {
+        return supplierAuthorizeService.getSupplierAuthorizeList(brandId);
+    }
+
+    @Override
+    public List<Long> getSupplierIds(String enterpriseName) {
+        return supplierInfoService.getSupplierIds(enterpriseName);
+    }
+
+    @Override
+    public List<Long> getSupplierIdsBySupplyArea(String areaname,String level) {
+        return supplyAreaService.getSupplierIdsBySupplyArea(areaname,level);
+    }
+
+    @Override
+    public List<Long> getContractIdBySupplySupplierID(Set<Long> SupplierID) {
+        return contractSupplyService.list(
+            Wrappers.lambdaQuery(ContractSupply.class)
+                .in(ContractSupply::getSupplierId, SupplierID)
+                .select(ContractSupply::getId)
+        ).stream().map(ContractSupply::getId).collect(Collectors.toList());
+    }
+
+    @Override
+    public Map<Long, Long> contractToSupplierMap(List<Long> contractSupplyIds) {
+        List<ContractSupply> list = contractSupplyService.list(
+            new LambdaQueryWrapper<ContractSupply>().in(ContractSupply::getId, contractSupplyIds)
+        );
+        Map<Long, Long> contractToSupplierMap = list.stream()
+            .collect(Collectors.toMap(ContractSupply::getId, ContractSupply::getSupplierId));
+        return contractToSupplierMap;
+    }
+
+    @Override
+    public Map<Long, String> selectEnterpriseNameByIds(List<Long> ids) {
+        List<ContractSupply> list = contractSupplyService.list(
+            new LambdaQueryWrapper<ContractSupply>().in(ContractSupply::getId, ids)
+        );
+        if (CollUtil.isEmpty(list)) {
+            return Collections.emptyMap();
+        }
+
+        Map<Long, Long> contractToSupplierMap = list.stream()
+            .collect(Collectors.toMap(ContractSupply::getId, ContractSupply::getSupplierId));
+        Set<Long> supplierIds = new HashSet<>(contractToSupplierMap.values());
+        Map<Long, String> supplierNameMap = supplierInfoService.selectEnterpriseNameByIds(supplierIds);
+        // 5 转换为 contractSupplyId -> enterpriseName
+        Map<Long, String> result = new HashMap<>();
+        for (Map.Entry<Long, Long> entry : contractToSupplierMap.entrySet()) {
+
+            Long contractSupplyId = entry.getKey();
+            Long supplierId = entry.getValue();
+
+            String enterpriseName = supplierNameMap.get(supplierId);
+
+            if (enterpriseName != null) {
+                result.put(contractSupplyId, enterpriseName);
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Map<Long, SupplierAreaDTO> selectSupplierInfoByContractIds(List<Long> contractSupplyIds) {
+        // 1 查询合同供货
+        List<ContractSupply> list = contractSupplyService.list(
+            new LambdaQueryWrapper<ContractSupply>()
+                .in(ContractSupply::getId, contractSupplyIds)
+        );
+
+        if (CollUtil.isEmpty(list)) {
+            return Collections.emptyMap();
+        }
+
+        // contractSupplyId -> supplierId
+        Map<Long, Long> contractToSupplierMap = list.stream()
+            .collect(Collectors.toMap(
+                ContractSupply::getId,
+                ContractSupply::getSupplierId
+            ));
+
+        Set<Long> supplierIds = new HashSet<>(contractToSupplierMap.values());
+
+        // 2 查询供应商名称
+        Map<Long, String> supplierNameMap =
+            supplierInfoService.selectEnterpriseNameByIds(supplierIds);
+
+        // 3 查询供应区域
+        List<SupplyArea> areas = supplyAreaService.list(
+            new LambdaQueryWrapper<SupplyArea>()
+                .in(SupplyArea::getSupplierId, supplierIds)
+        );
+
+        Map<Long, List<SupplyArea>> areaGroup =
+            areas.stream().collect(Collectors.groupingBy(SupplyArea::getSupplierId));
+
+        Map<Long, SupplierAreaDTO> result = new HashMap<>();
+
+        for (ContractSupply cs : list) {
+
+            Long contractSupplyId = cs.getId();
+            Long supplierId = cs.getSupplierId();
+
+            SupplierAreaDTO vo = new SupplierAreaDTO();
+
+            // 企业名称
+            vo.setEnterpriseName(supplierNameMap.get(supplierId));
+
+            // 报价截止时间
+            vo.setEndTime(cs.getEndTime());
+
+            List<SupplyArea> supplierAreas = areaGroup.get(supplierId);
+
+            if (CollUtil.isNotEmpty(supplierAreas)) {
+
+                List<String> provinces = new ArrayList<>();
+                List<String> cities = new ArrayList<>();
+
+                for (SupplyArea area : supplierAreas) {
+
+                    if ("1".equals(area.getLevel())) {
+                        provinces.add(area.getAreaName());
+                    }
+
+                    if ("2".equals(area.getLevel())) {
+                        cities.add(area.getAreaName());
+                    }
+                }
+
+                vo.setProvinceName(String.join(",", provinces));
+                vo.setCityName(String.join(",", cities));
+            }
+
+            result.put(contractSupplyId, vo);
+        }
+
+        return result;
+    }
+
+    @Override
+    public int updateExpiredAuthorizedStatus() {
+        return supplierAuthorizeService.updateExpiredAuthorizedStatus();
+    }
 }

+ 6 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierAuthorizeService.java

@@ -1,6 +1,7 @@
 package org.dromara.customer.service;
 
 import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.customer.api.domain.dto.SupplierAuthorizeDTO;
 import org.dromara.customer.domain.SupplierAuthorize;
 import org.dromara.customer.domain.vo.SupplierAuthorizeVo;
 import org.dromara.customer.domain.bo.SupplierAuthorizeBo;
@@ -52,6 +53,8 @@ public interface ISupplierAuthorizeService extends IService<SupplierAuthorize>{
      */
     Boolean insertByBo(SupplierAuthorizeBo bo);
 
+    List<SupplierAuthorizeDTO> getSupplierAuthorizeList(Long brandId);
+
     /**
      * 修改供应能力查询
      *
@@ -80,4 +83,7 @@ public interface ISupplierAuthorizeService extends IService<SupplierAuthorize>{
     SupplierAuthorizeVo getBrandAuthorizeDetail(Long id);
 
     boolean exam(SupplierAuthorizeBo bo);
+
+    int updateExpiredAuthorizedStatus();
+
 }

+ 4 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierInfoService.java

@@ -120,4 +120,8 @@ public interface ISupplierInfoService extends IService<SupplierInfo> {
     List<SupplierInfoVo> getNameList();
 
     int scmUpdateByBo(SupplierInfoBo bo);
+
+    List<Long> getSupplierIds(String enterpriseName);
+
+    Map<Long, String> selectEnterpriseNameByIds(Set<Long> ids);
 }

+ 2 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplyAreaService.java

@@ -76,4 +76,6 @@ public interface ISupplyAreaService extends IService<SupplyArea>{
     int deleteBySupplierId(Long supplierId);
 
     TableDataInfo<SupplyAreaVo> querySrmPageList(SupplyAreaBo bo, PageQuery pageQuery);
+
+    List<Long> getSupplierIdsBySupplyArea(String areaname,String level);
 }

+ 48 - 7
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAuthorizeServiceImpl.java

@@ -1,6 +1,7 @@
 package org.dromara.customer.service.impl;
 
 import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.apache.dubbo.config.annotation.DubboReference;
@@ -14,6 +15,7 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.customer.api.domain.dto.SupplierAuthorizeDTO;
 import org.dromara.customer.domain.QualificationFile;
 import org.dromara.customer.domain.SupplierInfo;
 import org.dromara.customer.domain.SupplyArea;
@@ -39,6 +41,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.springframework.util.CollectionUtils;
 
 import java.text.SimpleDateFormat;
+import java.time.LocalDateTime;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
@@ -140,6 +143,38 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
         return flag;
     }
 
+    @Override
+    public List<SupplierAuthorizeDTO> getSupplierAuthorizeList(Long brandId) {
+        LambdaQueryWrapper<SupplierAuthorize> lqw = new LambdaQueryWrapper<>();
+        lqw.eq(SupplierAuthorize::getBrandId, brandId);
+        List<SupplierAuthorizeVo> supplierAuthorizeVos = baseMapper.selectVoList(lqw);
+        setSupplierNames(supplierAuthorizeVos);
+        // 使用AddressAreaService查询地区信息
+        setSupplyAreaInfo(supplierAuthorizeVos);
+
+        //一级 二级 三级 品目
+        Map<Long,Long> categoryMap = supplierAuthorizeVos.stream()
+            .filter(item -> item.getId() != null && item.getCategoryId() != null)
+            .collect(Collectors.toMap(
+                SupplierAuthorizeVo::getId,
+                item ->item.getCategoryId()
+            ));
+
+        Map<Long, Map<String, String>> categorysMap = remoteCategoryService.getallCategoryNameById(categoryMap);
+
+        supplierAuthorizeVos.forEach(item -> {
+            Map<String, String> stringStringMap = categorysMap.get(item.getId());
+            item.setCategorysMap(stringStringMap);
+        });
+        return supplierAuthorizeVos.stream()
+            .map(vo -> {
+                SupplierAuthorizeDTO dto = new SupplierAuthorizeDTO();
+                BeanUtils.copyProperties(vo, dto);
+                return dto;
+            })
+            .collect(Collectors.toList());
+    }
+
     /**
      * 修改供应能力查询
      *
@@ -414,6 +449,18 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
         return update;
     }
 
+    @Override
+    public int updateExpiredAuthorizedStatus() {
+        LambdaUpdateWrapper<SupplierAuthorize> updateWrapper = new LambdaUpdateWrapper<>();
+
+        updateWrapper
+            .lt(SupplierAuthorize::getAuthorizationEndTime, LocalDateTime.now())
+            .ne(SupplierAuthorize::getAuthorizedStatus, "2")
+            .set(SupplierAuthorize::getAuthorizedStatus, "2");
+
+        return baseMapper.update(null, updateWrapper);
+    }
+
 
     private Map<Long, String> supplierBrandMap(List<Long> ids){
         List<SupplierAuthorize> authorizeList = baseMapper.selectList(
@@ -587,13 +634,7 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
             item.setCategorysMap(stringStringMap);
         });
         // 直接创建新的分页对象,包含处理后的数据
-        Page<SupplierAuthorizeVo> resultPage = new Page<>();
-        resultPage.setCurrent(supplierAuthorizePage.getCurrent());
-        resultPage.setSize(supplierAuthorizePage.getSize());
-        resultPage.setTotal(supplierAuthorizePage.getTotal());
-        resultPage.setRecords(supplierAuthorizeVos);
-
-        return TableDataInfo.build(resultPage);
+        return TableDataInfo.build(supplierAuthorizePage);
     }
 
     @Override

+ 33 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java

@@ -2270,4 +2270,37 @@ public class SupplierInfoServiceImpl extends ServiceImpl<SupplierInfoMapper, Sup
         SupplierInfo update = MapstructUtils.convert(bo, SupplierInfo.class);
         return baseMapper.updateById(update);
     }
+
+    @Override
+    public List<Long> getSupplierIds(String enterpriseName) {
+        LambdaQueryWrapper<SupplierInfo> lqw = new LambdaQueryWrapper<>();
+        lqw.like(StringUtils.isNotBlank(enterpriseName), SupplierInfo::getEnterpriseName, enterpriseName);
+        lqw.select(SupplierInfo::getId);
+        return baseMapper.selectList(lqw).stream().map(SupplierInfo::getId).collect(Collectors.toList());
+    }
+
+    @Override
+    public Map<Long, String> selectEnterpriseNameByIds(Set<Long> ids) {
+        if (ids == null || ids.isEmpty()) {
+            return Collections.emptyMap();
+        }
+
+        // 限制批量大小
+        if (ids.size() > 1000) {
+            throw new IllegalArgumentException("Batch size exceeds limit: " + ids.size());
+        }
+
+        List<SupplierInfo> supplierInfoList = baseMapper.selectByIds(ids);
+        Map<Long, String> resultMap = new HashMap<>(ids.size());
+
+        // 初始化所有请求的 ID 为 null
+        ids.forEach(id -> resultMap.put(id, null));
+
+        if (supplierInfoList != null) {
+            supplierInfoList.stream()
+                .filter(supplier -> supplier.getId() != null && supplier.getEnterpriseName() != null)
+                .forEach(supplier -> resultMap.put(supplier.getId(), supplier.getEnterpriseName()));
+        }
+        return resultMap;
+    }
 }

+ 9 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplyAreaServiceImpl.java

@@ -175,6 +175,15 @@ public class SupplyAreaServiceImpl  extends ServiceImpl<SupplyAreaMapper, Supply
         return TableDataInfo.build(result);
     }
 
+    @Override
+    public List<Long> getSupplierIdsBySupplyArea(String areaname , String level) {
+        LambdaQueryWrapper<SupplyArea> lqw = new LambdaQueryWrapper<>();
+        lqw.like(SupplyArea::getAreaName, areaname);
+        lqw.eq(SupplyArea::getLevel, level);
+        lqw.select(SupplyArea::getSupplierId);
+        return baseMapper.selectList(lqw).stream().map(SupplyArea::getSupplierId).collect(Collectors.toList());
+    }
+
     /**
      * 分页查询供应区域列表
      *

+ 3 - 3
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePullController.java

@@ -409,7 +409,7 @@ public class ZhongChePullController {
         return zcr;
     }
 
-    //TODO 5.2.3	商品上下架状态变更
+    // 5.2.3	商品上下架状态变更
     @PostMapping("/egoods/status/update")
     public GoodsStatusUpdateVo egoodsStatusUpdate(@RequestBody GoodsStatusUpdateBo bo) {
 
@@ -418,7 +418,7 @@ public class ZhongChePullController {
         return zcr;
     }
 
-    //TODO 5.2.4	商品图片变更
+    // 5.2.4	商品图片变更
     @PostMapping("/egoods/imgs/update")
     public GoodsImageUpdateVo egoodsImgsUpdate(@RequestBody GoodsImageUpdateBo bo) {
         ZCR responseDto = doZcPost("/api/egoods/imgs/update", bo);
@@ -426,7 +426,7 @@ public class ZhongChePullController {
         return zcr;
     }
 
-    //TODO 5.2.5	商品规格信息变更
+    // 5.2.5	商品规格信息变更
     @PostMapping("/egoods/properties/update")
     public GoodsUpdateVo egoodsPropertiesUpdate(@RequestBody GoodsPropertiesUpdateBo bo) {
         ZCR responseDto = doZcPost("/api/egoods/properties/update", bo);

+ 33 - 0
ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/ContractSupplyJobTask.java

@@ -0,0 +1,33 @@
+package org.dromara.job.snailjob;
+
+import com.aizuda.snailjob.client.job.core.annotation.JobExecutor;
+import com.aizuda.snailjob.client.job.core.dto.JobArgs;
+import com.aizuda.snailjob.client.model.ExecuteResult;
+import com.aizuda.snailjob.common.log.SnailJobLog;
+import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.customer.api.RemoteSupplierContractService;
+import org.dromara.customer.api.RemoteSupplierInfoService;
+import org.springframework.stereotype.Component;
+
+/**
+ * author
+ * 时间:2026/3/12,18:52
+ */
+@Component
+@JobExecutor(name = "ContractSupplyJobTask")
+@RequiredArgsConstructor
+public class ContractSupplyJobTask {
+    @DubboReference
+    private final RemoteSupplierInfoService remoteSupplierInfoService;
+    public ExecuteResult jobExecute(JobArgs jobArgs){
+        // 更新过期合同状态
+        int i = remoteSupplierInfoService.updateExpiredAuthorizedStatus();
+        if (i > 0){
+            SnailJobLog.REMOTE.info("商品授权状态更新完成");
+        }else {
+            SnailJobLog.REMOTE.info("商品授权状态更新失败");
+        }
+        return ExecuteResult.success("商品授权状态更新完成");
+    }
+}

+ 9 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ContractProductController.java

@@ -46,6 +46,15 @@ public class ContractProductController extends BaseController {
         return contractProductService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 供应链查询   给scm用的
+     */
+    @GetMapping("/scm/list")
+    public TableDataInfo<ContractProductVo> scmList(ContractProductBo bo, PageQuery pageQuery) {
+        return contractProductService.queryscmPageList(bo, pageQuery);
+    }
+
+
     /**
      * 导出合同产品关联列表
      */

+ 4 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBrandController.java

@@ -6,6 +6,8 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.customer.api.RemoteSupplierInfoService;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -37,6 +39,8 @@ public class ProductBrandController extends BaseController {
 
     private final IProductBrandService productBrandService;
 
+
+
     /**
      * 查询产品品牌信息列表
      */

+ 22 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ContractProductBo.java

@@ -70,5 +70,27 @@ public class ContractProductBo extends BaseEntity {
      */
     private String status;
 
+    /**
+     * 产品名称
+     */
+    private String productName;
+
+    /**
+     * 供应商名称
+     */
+    private String enterpriseName;
+
+    /**
+     * 供应区域(省)
+     */
+    private String provinceName;
+    /**
+     * 供应区域(市)
+     */
+    private String cityName;
+
+    private String province;
+
+    private String city;
 
 }

+ 88 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ContractProductVo.java

@@ -10,6 +10,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -90,5 +91,92 @@ public class ContractProductVo implements Serializable {
     @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
     private String status;
 
+    /**
+     * 产品名称
+     */
+    private String productName;
+
+    /**
+     * 产品图片
+     */
+    private String productImage;
+
+    /**
+     * 单位名称
+     */
+    private String unitName;
+
+    /**
+     * 最小起订量
+     */
+    private Long minOrderQuantity;
+
+    /**
+     * 底级分类名称
+     */
+    private String bottomCategoryName;
+
+    /**
+     * 市场价
+     * */
+    private BigDecimal marketPrice;
+
+    /**
+     * 会员价格
+     */
+    private BigDecimal memberPrice;
+
+    /**
+     * 最低销售价格
+     */
+    private BigDecimal minSellingPrice;
+
+    /**
+     * 总库存
+     * */
+    private Long totalInventory;
+    /**
+     * 当前可用库存
+     * */
+    private Long nowInventory;
+
+    /**
+     * 虚拟库存
+     * */
+    private Long virtualInventory;
+
+    /**
+     * 品牌id
+     */
+    private Long brandId;
+
+    /**
+     * 品牌名称
+     */
+    private String brandName;
+
+    /**
+     * 供应商名称
+     */
+    private String enterpriseName;
+
+    /**
+     * 供应区域(省)
+     */
+    private String provinceName;
+    /**
+     * 供应区域(市)
+     */
+    private String cityName;
+
+    /**
+     * 报价截止日期
+     */
+    private Date endTime;
+
+    /**
+     * 毛利率
+     */
+    private BigDecimal grossProfitRate;
 
 }

+ 4 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBrandVo.java

@@ -4,6 +4,7 @@ import org.dromara.common.translation.annotation.Translation;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.customer.api.domain.dto.SupplierAuthorizeDTO;
 import org.dromara.easyes.annotation.IndexName;
 import org.dromara.product.domain.ProductBrand;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
@@ -16,7 +17,7 @@ import lombok.Data;
 import java.io.Serial;
 import java.io.Serializable;
 import java.util.Date;
-
+import java.util.List;
 
 
 /**
@@ -173,5 +174,7 @@ public class ProductBrandVo implements Serializable {
 
     private Date createTime;
 
+    List<SupplierAuthorizeDTO> supplierAuthorizeList;
+
 
 }

+ 2 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IContractProductService.java

@@ -67,4 +67,6 @@ public interface IContractProductService extends IService<ContractProduct>{
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    TableDataInfo<ContractProductVo> queryscmPageList(ContractProductBo bo, PageQuery pageQuery);
 }

+ 217 - 3
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ContractProductServiceImpl.java

@@ -1,6 +1,9 @@
 package org.dromara.product.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import com.baomidou.mybatisplus.core.conditions.Wrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -10,6 +13,15 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.customer.api.RemoteSupplierInfoService;
+import org.dromara.customer.api.domain.dto.SupplierAreaDTO;
+import org.dromara.easyes.core.biz.EsPageInfo;
+import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
+import org.dromara.product.domain.ProductBase;
+import org.dromara.product.domain.vo.ProductBaseVo;
+import org.dromara.product.esmapper.ProductEsMapper;
+import org.dromara.product.mapper.ProductBaseMapper;
+import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.dromara.product.domain.bo.ContractProductBo;
 import org.dromara.product.domain.vo.ContractProductVo;
@@ -17,9 +29,8 @@ import org.dromara.product.domain.ContractProduct;
 import org.dromara.product.mapper.ContractProductMapper;
 import org.dromara.product.service.IContractProductService;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 合同产品关联Service业务层处理
@@ -34,6 +45,13 @@ public class ContractProductServiceImpl  extends ServiceImpl<ContractProductMapp
 
     private final ContractProductMapper baseMapper;
 
+    @DubboReference
+    private final RemoteSupplierInfoService remoteSupplierInfoService;
+
+    private final ProductBaseMapper productBaseMapper;
+
+    private final ProductEsMapper esMapper;
+
     /**
      * 查询合同产品关联
      *
@@ -137,4 +155,200 @@ public class ContractProductServiceImpl  extends ServiceImpl<ContractProductMapp
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    @Override
+    public TableDataInfo<ContractProductVo> queryscmPageList(ContractProductBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ContractProduct> lqw = new LambdaQueryWrapper<>();
+
+        // 用于存最终 supplierId
+        Set<Long> supplierIdSet = null;
+
+        // =========================
+        // 1 供应商名称
+        // =========================
+        if (StringUtils.isNotBlank(bo.getEnterpriseName())) {
+
+            List<Long> supplierIds =
+                remoteSupplierInfoService.getSupplierIds(bo.getEnterpriseName());
+
+            supplierIdSet = new HashSet<>(supplierIds);
+        }
+        // =========================
+        // 2 省
+        // =========================
+        if (StringUtils.isNotBlank(bo.getProvinceName())) {
+
+            List<Long> supplierIds =
+                remoteSupplierInfoService.getSupplierIdsBySupplyArea(
+                    bo.getProvinceName(), "1");
+
+            if (supplierIdSet == null) {
+                supplierIdSet = new HashSet<>(supplierIds);
+            } else {
+                supplierIdSet.retainAll(supplierIds);
+            }
+        }
+        // =========================
+        // 3 市
+        // =========================
+        if (StringUtils.isNotBlank(bo.getCityName())) {
+
+            List<Long> supplierIds =
+                remoteSupplierInfoService.getSupplierIdsBySupplyArea(
+                    bo.getCityName(), "2");
+
+            if (supplierIdSet == null) {
+                supplierIdSet = new HashSet<>(supplierIds);
+            } else {
+                supplierIdSet.retainAll(supplierIds);
+            }
+        }
+
+        // =========================
+        // 4 产品名称
+        // =========================
+        if (StringUtils.isNotBlank(bo.getProductName())) {
+
+            if (!esMapper.existsIndex("productbasevo")) {
+                LambdaQueryWrapper<ProductBase> lqw1 = new LambdaQueryWrapper<>();
+                lqw1.like(ProductBase::getItemName, bo.getProductName());
+                lqw1.select(ProductBase::getId);
+
+                List<Long> productIds = productBaseMapper.selectList(lqw1)
+                    .stream()
+                    .map(ProductBase::getId)
+                    .collect(Collectors.toList());
+                if (CollUtil.isNotEmpty(productIds)) {
+                    lqw.in(ContractProduct::getProductId, productIds);
+                } else {
+                    return TableDataInfo.build(new Page<>());
+                }
+            }
+            LambdaEsQueryWrapper<ProductBaseVo> esQueryWrapper = new LambdaEsQueryWrapper<ProductBaseVo>()
+                .like(ProductBaseVo::getItemName, bo.getProductName())
+                .select(ProductBaseVo::getId);
+            List<ProductBaseVo> esListInfo = esMapper.selectList(esQueryWrapper);
+            List<Long> collect = esListInfo.stream().map(ProductBaseVo::getId)
+                .collect(Collectors.toList());
+            if (CollUtil.isNotEmpty(collect)) {
+                lqw.in(ContractProduct::getProductId, collect);
+            } else {
+                return TableDataInfo.build(new Page<>());
+            }
+        }
+
+        // =========================
+        // 5 产品编号
+        // =========================
+        if (StringUtils.isNotBlank(bo.getProductNo())) {
+            lqw.eq(ContractProduct::getProductNo, bo.getProductNo());
+        }
+
+        // =========================
+        // 6 supplierId 过滤
+        // =========================
+        if (CollUtil.isNotEmpty(supplierIdSet)) {
+            List<Long> contractIds = remoteSupplierInfoService.getContractIdBySupplySupplierID(supplierIdSet);
+            if (CollUtil.isNotEmpty(contractIds)) {
+                lqw.in(ContractProduct::getContractSupplyId, contractIds);
+            } else {
+                return TableDataInfo.build(new Page<>());
+            }
+        }
+
+        Page<ContractProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        List<ContractProductVo> records = result.getRecords();
+        if (records.isEmpty()) {
+            return TableDataInfo.build(result);
+        }
+        List<Long> productIds = records.stream()
+            .map(ContractProductVo::getProductId)
+            .filter(Objects::nonNull)
+            .distinct()
+            .collect(Collectors.toList());
+
+        LambdaEsQueryWrapper<ProductBaseVo> esQueryWrapper = new LambdaEsQueryWrapper<ProductBaseVo>()
+            .in(ProductBaseVo::getId, productIds);
+        List<ProductBaseVo> productVos;
+        try {
+            if (!esMapper.existsIndex("productbasevo")) {
+                log.warn("ES索引 [productbasevo] 不存在,降级到数据库查询");
+                // 可调用 fallback 方法
+                productVos = productBaseMapper.selectList(
+                    new LambdaQueryWrapper<ProductBase>().in(ProductBase::getId, productIds)
+                ).stream().map(pb -> {
+                    ProductBaseVo vo = new ProductBaseVo();
+                    BeanUtils.copyProperties(pb, vo);
+                    return vo;
+                }).collect(Collectors.toList());
+            }
+
+            EsPageInfo<ProductBaseVo> esPageInfo = esMapper.pageQuery(esQueryWrapper, 1, productIds.size());
+            productVos = esPageInfo.getList();
+
+        } catch (Exception e) {
+            log.error("ES查询商品信息异常: {}", e.getMessage(), e);
+            productVos = productBaseMapper.selectList(
+                new LambdaQueryWrapper<ProductBase>().in(ProductBase::getId, productIds)
+            ).stream().map(pb -> {
+                ProductBaseVo vo = new ProductBaseVo();
+                BeanUtils.copyProperties(pb, vo);
+                return vo;
+            }).collect(Collectors.toList());
+        }
+
+        Map<Long, ProductBaseVo> productMap = productVos.stream()
+            .collect(Collectors.toMap(ProductBaseVo::getId, p -> p));
+
+        // ----------------------
+        // 4️⃣ 批量填充 VO
+        // ----------------------
+        for (ContractProductVo vo : records) {
+            if (vo.getProductId() != null && productMap.containsKey(vo.getProductId())) {
+                ProductBaseVo pb = productMap.get(vo.getProductId());
+                vo.setProductName(pb.getItemName());
+                vo.setProductImage(pb.getProductImage());
+                vo.setBrandId(pb.getBrandId());
+                vo.setBrandName(pb.getBrandName());
+                vo.setUnitName(pb.getUnitName());
+                vo.setMarketPrice(pb.getMarketPrice());
+                vo.setMemberPrice(pb.getMemberPrice());
+                vo.setMinOrderQuantity(pb.getMinOrderQuantity());
+                vo.setMinSellingPrice(pb.getMinSellingPrice());
+                vo.setTotalInventory(pb.getTotalInventory());
+                vo.setNowInventory(pb.getNowInventory());
+                vo.setVirtualInventory(pb.getVirtualInventory());
+                vo.setBottomCategoryName(pb.getBottomCategoryName());
+            }
+        }
+
+        //供应商名称回填
+        List<Long> contractSupplyIds = records.stream()
+            .map(ContractProductVo::getContractSupplyId)
+            .filter(Objects::nonNull)
+            .distinct()
+            .collect(Collectors.toList());
+
+
+        Map<Long, SupplierAreaDTO> suppliers = remoteSupplierInfoService.selectSupplierInfoByContractIds(contractSupplyIds);
+
+        for (ContractProductVo vo : records) {
+            Long contractSupplyId = vo.getContractSupplyId();
+
+            SupplierAreaDTO supplier = suppliers.get(contractSupplyId);
+
+            if (supplier != null) {
+
+                // 企业名称
+                vo.setEnterpriseName(supplier.getEnterpriseName());
+
+                // 供应区域
+                vo.setProvinceName(supplier.getProvinceName());
+                vo.setCityName(supplier.getCityName());
+                vo.setEndTime(supplier.getEndTime());
+            }
+        }
+        return TableDataInfo.build(result);
+    }
+
 }

+ 0 - 2
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java

@@ -477,8 +477,6 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         if (ObjectUtil.isNotEmpty(bo.getIds())){
             productBaseVoLambdaEsQueryWrapper.in(ProductBaseVo::getId, bo.getIds().split(","));
         }
-
-
         return productBaseVoLambdaEsQueryWrapper;
     }
 

+ 10 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBrandServiceImpl.java

@@ -9,6 +9,7 @@ import co.elastic.clients.elasticsearch._types.aggregations.LongTermsBucket;
 import co.elastic.clients.elasticsearch.core.SearchResponse;
 import com.baomidou.mybatisplus.core.metadata.IPage;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -18,6 +19,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.customer.api.RemoteSupplierInfoService;
+import org.dromara.customer.api.domain.dto.SupplierAuthorizeDTO;
 import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
 import org.dromara.product.domain.*;
 import org.dromara.product.domain.vo.*;
@@ -67,6 +70,9 @@ public class ProductBrandServiceImpl  extends ServiceImpl<ProductBrandMapper, Pr
 
     private final ProductIndustrialFloorLinkMapper productIndustrialFloorLinkMapper;
 
+    @DubboReference
+    private final RemoteSupplierInfoService remoteSupplierInfoService;
+
     // Redis key前缀,用于存储品牌编号自增的计数器
     private static final String BRAND_NO_COUNTER_KEY = "product:brand:no:counter";
     // 品牌编号的位数(6位)
@@ -99,7 +105,10 @@ public class ProductBrandServiceImpl  extends ServiceImpl<ProductBrandMapper, Pr
      */
     @Override
     public ProductBrandVo queryById(Long id){
-        return baseMapper.selectVoById(id);
+        List<SupplierAuthorizeDTO> supplierAuthorizeList = remoteSupplierInfoService.getSupplierAuthorizeList(id);
+        ProductBrandVo productBrandVo = baseMapper.selectVoById(id);
+        productBrandVo.setSupplierAuthorizeList(supplierAuthorizeList);
+        return productBrandVo;
     }
 
     /**