tjxt пре 2 месеци
родитељ
комит
c3b7ffd2e6
43 измењених фајлова са 1932 додато и 71 уклоњено
  1. 2 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteSupplierTypeVo.java
  2. 3 1
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  3. 9 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/EnterpriseScaleController.java
  4. 9 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/IndustryCategoryController.java
  5. 114 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierAddressController.java
  6. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierAuthorizeController.java
  7. 13 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierContractController.java
  8. 117 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierAddress.java
  9. 4 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierContract.java
  10. 13 9
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierInfo.java
  11. 99 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierAddressBo.java
  12. 12 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierAuthorizeBo.java
  13. 64 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierContractBo.java
  14. 16 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/dto/ContractCountDTO.java
  15. 18 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyVo.java
  16. 125 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierAddressVo.java
  17. 18 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierAuthorizeVo.java
  18. 3 7
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierContractVo.java
  19. 3 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierInfoVo.java
  20. 81 11
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierInformationVo.java
  21. 51 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/enums/ContractSupplierStatusEnum.java
  22. 15 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/SupplierAddressMapper.java
  23. 72 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierAddressService.java
  24. 91 3
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/ContractSupplyServiceImpl.java
  25. 2 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/EnterpriseScaleServiceImpl.java
  26. 152 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAddressServiceImpl.java
  27. 100 12
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAuthorizeServiceImpl.java
  28. 62 18
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContractServiceImpl.java
  29. 128 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java
  30. 7 0
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SupplierAddressMapper.xml
  31. 1 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteCategoryServiceImpl.java
  32. 106 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/ProductTaxrateController.java
  33. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SupplierLevelController.java
  34. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SupplierTypeController.java
  35. 67 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ProductTaxrate.java
  36. 54 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ProductTaxrateBo.java
  37. 64 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProductTaxrateVo.java
  38. 2 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SupplierLevelVo.java
  39. 6 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SupplierTypeVo.java
  40. 15 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/ProductTaxrateMapper.java
  41. 70 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IProductTaxrateService.java
  42. 133 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ProductTaxrateServiceImpl.java
  43. 7 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/ProductTaxrateMapper.xml

+ 2 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteSupplierTypeVo.java

@@ -8,6 +8,8 @@ import lombok.Data;
  */
 @Data
 public class RemoteSupplierTypeVo {
+    private long id;
+
     private String typeId;
 
     private String typeName;

+ 3 - 1
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -77,7 +77,9 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "order_product",
         "com_",
         "product_",
-        "supplier_level"
+        "supplier_level",
+        "enterprise_scale",
+        "industry_category"
 
 
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法

+ 9 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/EnterpriseScaleController.java

@@ -40,12 +40,20 @@ public class EnterpriseScaleController extends BaseController {
     /**
      * 查询企业规模列表
      */
-    @SaCheckPermission("customer:enterpriseScale:list")
+    //@SaCheckPermission("customer:enterpriseScale:list")
     @GetMapping("/list")
     public TableDataInfo<EnterpriseScaleVo> list(EnterpriseScaleBo bo, PageQuery pageQuery) {
         return enterpriseScaleService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 查询企业规模列表
+     */
+    @GetMapping("/getlist")
+    public R<List<EnterpriseScaleVo>> getlist(EnterpriseScaleBo bo) {
+        return R.ok(enterpriseScaleService.queryList(bo));
+    }
+
     /**
      * 导出企业规模列表
      */

+ 9 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/IndustryCategoryController.java

@@ -40,12 +40,20 @@ public class IndustryCategoryController extends BaseController {
     /**
      * 查询所属行业列表
      */
-    @SaCheckPermission("customer:industryCategory:list")
+    //@SaCheckPermission("customer:industryCategory:list")
     @GetMapping("/list")
     public TableDataInfo<IndustryCategoryVo> list(IndustryCategoryBo bo, PageQuery pageQuery) {
         return industryCategoryService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 查询所属行业列表供应商
+     */
+    @GetMapping("/getlist")
+    public R<List<IndustryCategoryVo>> list(IndustryCategoryBo bo) {
+        return R.ok(industryCategoryService.queryList(bo));
+    }
+
     /**
      * 导出所属行业列表
      */

+ 114 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierAddressController.java

@@ -0,0 +1,114 @@
+package org.dromara.customer.controller;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.customer.domain.vo.SupplierAddressVo;
+import org.dromara.customer.domain.bo.SupplierAddressBo;
+import org.dromara.customer.service.ISupplierAddressService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 供应商地址
+ * 前端访问路由地址为:/supplierAddress/supplieraddress
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/supplieraddress")
+public class SupplierAddressController extends BaseController {
+
+    private final ISupplierAddressService supplierAddressService;
+
+    /**
+     * 根据supplierID查询地址信息
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:list")
+    @GetMapping("/supplierAddressById")
+    public R<List<SupplierAddressVo>> list(SupplierAddressBo bo) {
+        return R.ok(supplierAddressService.getSupplierAddressById(bo));
+    }
+    /**
+     * 查询供应商地址列表
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:list")
+    @GetMapping("/list")
+    public TableDataInfo<SupplierAddressVo> list(SupplierAddressBo bo, PageQuery pageQuery) {
+        return supplierAddressService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出供应商地址列表
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:export")
+    @Log(title = "供应商地址", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SupplierAddressBo bo, HttpServletResponse response) {
+        List<SupplierAddressVo> list = supplierAddressService.queryList(bo);
+        ExcelUtil.exportExcel(list, "供应商地址", SupplierAddressVo.class, response);
+    }
+
+    /**
+     * 获取供应商地址详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:query")
+    @GetMapping("/{id}")
+    public R<SupplierAddressVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(supplierAddressService.queryById(id));
+    }
+
+    /**
+     * 新增供应商地址
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:add")
+    @Log(title = "供应商地址", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SupplierAddressBo bo) {
+        return toAjax(supplierAddressService.insertByBo(bo));
+    }
+
+    /**
+     * 修改供应商地址
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:edit")
+    @Log(title = "供应商地址", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SupplierAddressBo bo) {
+        return toAjax(supplierAddressService.updateByBo(bo));
+    }
+
+    /**
+     * 删除供应商地址
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("supplierAddress:supplieraddress:remove")
+    @Log(title = "供应商地址", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(supplierAddressService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierAuthorizeController.java

@@ -83,7 +83,7 @@ public class SupplierAuthorizeController extends BaseController {
     /**
      * 供应能力查询信息列表
      */
-    @SaCheckPermission("supplier:area:list")
+    @SaCheckPermission("supplier:supplierauthorize:list")
     @GetMapping("/getSupplyCapacityList")
     public TableDataInfo<SupplierAuthorizeVo> getSupplyCapacityList(SupplierAuthorizeBo bo, PageQuery pageQuery) {
         return supplierAuthorizeService.getSupplyCapacityList(bo, pageQuery);

+ 13 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierContractController.java

@@ -46,6 +46,19 @@ public class SupplierContractController extends BaseController {
         return supplierContractService.queryPageList(bo, pageQuery);
     }
 
+    /**
+     * 获取合同列表
+     *
+     *
+     */
+    @GetMapping("/getListbyId")
+    public R<List<SupplierContractVo>> getListbyId(SupplierContractBo bo) {
+        return R.ok(supplierContractService.queryList(bo));
+
+    }
+
+
+
     /**
      * 导出合同管理列表
      */

+ 117 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierAddress.java

@@ -0,0 +1,117 @@
+package org.dromara.customer.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 供应商地址对象 supplier_address
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("supplier_address")
+public class SupplierAddress extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 供应商编号
+     */
+    private String supplierNo;
+
+    /**
+     * 供应商编号ID
+     */
+    private Long supplierId;
+
+    /**
+     * 配送公司名称
+     */
+    private String shippingCompany;
+
+    /**
+     * 发货人姓名
+     */
+    private String shipperName;
+
+    /**
+     * 发货人电话
+     */
+    private String shipperPhone;
+
+    /**
+     * 邮政编码
+     */
+    private String shippingPostCode;
+
+    /**
+     * 省
+     */
+    private String shippingProvincial;
+
+    /**
+     * 市
+     */
+    private String shippingCity;
+
+    /**
+     * 区/县
+     */
+    private String shippingCounty;
+
+    /**
+     * 详细地址
+     */
+    private String shippingAddress;
+
+    /**
+     * 推送状态(例如:0-未推送, 1-已推送, 16-推送失败)
+     */
+    private String pushStatus;
+
+    /**
+     * 是否为自身地址(1-是, 0-否)
+     */
+    private String isSelf;
+
+    /**
+     * 地址类型(例如:1-注册地址, 2-经营地址, 3-发货地址)
+     */
+    private String type;
+
+    /**
+     * 地址编码
+     */
+    private String addressNo;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 4 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierContract.java

@@ -4,6 +4,8 @@ import org.dromara.common.tenant.core.TenantEntity;
 import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
+
+import java.math.BigDecimal;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 
@@ -82,7 +84,7 @@ public class SupplierContract extends TenantEntity {
     /**
      * 税率(如13%/9%/6%)
      */
-    private String taxRate;
+    private BigDecimal taxRate;
 
     /**
      * 结算方式(如月结/季结/一次性)
@@ -90,7 +92,7 @@ public class SupplierContract extends TenantEntity {
     private String settlementMethod;
 
     /**
-     * 合同描述(核心条款/备注)
+     * 合同说明
      */
     private String contractDescription;
 

+ 13 - 9
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierInfo.java

@@ -281,15 +281,6 @@ public class SupplierInfo extends BaseEntity {
      */
     private Long pushStatus;
 
-    /**
-     * 创建时间
-     */
-    private Date created;
-
-    /**
-     * 修改时间
-     */
-    private Date modify;
 
     /**
      * 有效期开始时间
@@ -322,4 +313,17 @@ public class SupplierInfo extends BaseEntity {
     private Long cooperative;
 
 
+    /**
+     * 供应区域(省)
+     */
+    @TableField(exist = false)
+    private String province;
+
+    /**
+     * 供应区域(市)
+     */
+    @TableField(exist = false)
+    private String city;
+
+
 }

+ 99 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierAddressBo.java

@@ -0,0 +1,99 @@
+package org.dromara.customer.domain.bo;
+
+import org.dromara.customer.domain.SupplierAddress;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 供应商地址业务对象 supplier_address
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SupplierAddress.class, reverseConvertGenerate = false)
+public class SupplierAddressBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 供应商编号
+     */
+    private String supplierNo;
+
+    /**
+     * 供应商编号ID
+     */
+    private Long supplierId;
+
+    /**
+     * 配送公司名称
+     */
+    private String shippingCompany;
+
+    /**
+     * 发货人姓名
+     */
+    private String shipperName;
+
+    /**
+     * 发货人电话
+     */
+    private String shipperPhone;
+
+    /**
+     * 邮政编码
+     */
+    private String shippingPostCode;
+
+    /**
+     * 省
+     */
+    private String shippingProvincial;
+
+    /**
+     * 市
+     */
+    private String shippingCity;
+
+    /**
+     * 区/县
+     */
+    private String shippingCounty;
+
+    /**
+     * 详细地址
+     */
+    private String shippingAddress;
+
+    /**
+     * 推送状态(例如:0-未推送, 1-已推送, 16-推送失败)
+     */
+    private String pushStatus;
+
+    /**
+     * 是否为自身地址(1-是, 0-否)
+     */
+    private String isSelf;
+
+    /**
+     * 地址类型(例如:1-注册地址, 2-经营地址, 3-发货地址)
+     */
+    private String type;
+
+    /**
+     * 地址编码
+     */
+    private String addressNo;
+
+
+}

+ 12 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierAuthorizeBo.java

@@ -24,6 +24,8 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 @AutoMapper(target = SupplierAuthorize.class, reverseConvertGenerate = false)
 public class SupplierAuthorizeBo extends BaseEntity {
 
+    private Long id;
+
     /**
      * 供应商编号
      */
@@ -144,5 +146,15 @@ public class SupplierAuthorizeBo extends BaseEntity {
      */
     private String reviewFeedback;
 
+    /**
+     * 省份
+     */
+    private String province;
+
+    /**
+     *  城市
+     */
+    private String city;
+
 
 }

+ 64 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierContractBo.java

@@ -8,6 +8,8 @@ import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
+
+import java.math.BigDecimal;
 import java.util.Date;
 import com.fasterxml.jackson.annotation.JsonFormat;
 
@@ -32,5 +34,67 @@ public class SupplierContractBo extends BaseEntity {
      */
     private Long supplierId;
 
+    /**
+     * 供应商名称
+     */
+    private String supplierName;
+
+    /**
+     * 合同编号
+     */
+    private String contractNo;
+
+    /**
+     * 合同名称
+     */
+    private String contractName;
+
+    /**
+     * 合同类型(年度合作/项目采购/其他合作)
+     */
+    private Long contractType;
+
+    /**
+     * 合同生效时间
+     */
+    private Date contractStartTime;
+
+    /**
+     * 合同到期时间
+     */
+    private Date contractEndTime;
+
+    /**
+     * 合同状态(0待审核 1已签署 2已完成 3已到期 4审核未通过)
+     */
+    private Long contractStatus;
+
+    /**
+     * 到期提醒时间(单位:天,如提前7天提醒)
+     */
+    private Long demandReminderTime;
+
+    /**
+     * 税率(如13%/9%/6%)
+     */
+    private BigDecimal taxRate;
+
+    /**
+     * 合同金额
+     */
+    private Long contractAmount;
+
+    /**
+     * 合同说明
+     */
+    private String contractDescription;
+
+    /**
+     * 合同附件存储地址(多个附件用分隔符区分)
+     */
+    private String contractAttachment;
+
+
+
 
 }

+ 16 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/dto/ContractCountDTO.java

@@ -0,0 +1,16 @@
+package org.dromara.customer.domain.dto;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.RequiredArgsConstructor;
+
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class ContractCountDTO {
+    private long total;       // 合同总数
+    private long validCount;  // 有效合同数
+    private long invalidCount;// 失效合同数
+
+}

+ 18 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyVo.java

@@ -1,6 +1,8 @@
 package org.dromara.customer.domain.vo;
 
 import java.util.Date;
+
+import com.baomidou.mybatisplus.annotation.TableField;
 import com.fasterxml.jackson.annotation.JsonFormat;
 import org.dromara.customer.domain.ContractSupply;
 import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
@@ -42,11 +44,21 @@ public class ContractSupplyVo implements Serializable {
     @ExcelProperty(value = "供应商编号")
     private String supplyNo;
 
+    /**
+     * 供应商ID
+     */
+    private Long supplierId;
+
+    /**
+     * 供应商名称
+     */
+    private String supplierName;
+
     /**
      * 商品数量
      */
     @ExcelProperty(value = "商品数量")
-    private Long productNumber;
+    private Long productNumber = 0L;
 
     /**
      * 开始时间
@@ -67,5 +79,10 @@ public class ContractSupplyVo implements Serializable {
     @ExcelDictFormat(dictType = "contract_supplier_status")
     private String status;
 
+    /**
+     * 剩余时限(天)
+     */
+    private String timeRemaining;
+
 
 }

+ 125 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierAddressVo.java

@@ -0,0 +1,125 @@
+package org.dromara.customer.domain.vo;
+
+import org.dromara.customer.domain.SupplierAddress;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 供应商地址视图对象 supplier_address
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SupplierAddress.class)
+public class SupplierAddressVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 供应商编号
+     */
+    @ExcelProperty(value = "供应商编号")
+    private String supplierNo;
+
+    /**
+     * 供应商编号ID
+     */
+    @ExcelProperty(value = "供应商编号ID")
+    private Long supplierId;
+
+    /**
+     * 配送公司名称
+     */
+    @ExcelProperty(value = "配送公司名称")
+    private String shippingCompany;
+
+    /**
+     * 发货人姓名
+     */
+    @ExcelProperty(value = "发货人姓名")
+    private String shipperName;
+
+    /**
+     * 发货人电话
+     */
+    @ExcelProperty(value = "发货人电话")
+    private String shipperPhone;
+
+    /**
+     * 邮政编码
+     */
+    @ExcelProperty(value = "邮政编码")
+    private String shippingPostCode;
+
+    /**
+     * 省
+     */
+    @ExcelProperty(value = "省")
+    private String shippingProvincial;
+
+    /**
+     * 市
+     */
+    @ExcelProperty(value = "市")
+    private String shippingCity;
+
+    /**
+     * 区/县
+     */
+    @ExcelProperty(value = "区/县")
+    private String shippingCounty;
+
+    /**
+     * 详细地址
+     */
+    @ExcelProperty(value = "详细地址")
+    private String shippingAddress;
+
+    /**
+     * 推送状态(例如:0-未推送, 1-已推送, 16-推送失败)
+     */
+    @ExcelProperty(value = "推送状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "例=如:0-未推送,,1=-已推送,,1=6-推送失败")
+    private String pushStatus;
+
+    /**
+     * 是否为自身地址(1-是, 0-否)
+     */
+    @ExcelProperty(value = "是否为自身地址", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "1=-是,,0=-否")
+    private String isSelf;
+
+    /**
+     * 地址类型(例如:1-注册地址, 2-经营地址, 3-发货地址)
+     */
+    @ExcelProperty(value = "地址类型", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "例=如:1-注册地址,,2=-经营地址,,3=-发货地址")
+    private String type;
+
+    /**
+     * 地址编码
+     */
+    @ExcelProperty(value = "地址编码")
+    private String addressNo;
+
+
+}

+ 18 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierAuthorizeVo.java

@@ -54,12 +54,30 @@ public class SupplierAuthorizeVo implements Serializable {
      */
     private String supplierName;
 
+
+    /**
+     * 供货类目
+     */
+    private String supplyProCate;
+
+    /**
+     * 可供货品牌
+     */
+    private String supplyBrand;
+
+
+
     /**
      * 授权单编号
      */
     @ExcelProperty(value = "授权单编号")
     private String authorizeNo;
 
+    /**
+     * 有授权品牌
+     */
+    private String authBrand;
+
     /**
      * 品牌编号
      */

+ 3 - 7
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierContractVo.java

@@ -30,6 +30,7 @@ public class SupplierContractVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
+    private Long id;
     /**
      * 供应商编号
      */
@@ -54,7 +55,7 @@ public class SupplierContractVo implements Serializable {
     /**
      * 合同类型(年度合作/项目采购/其他合作)
      */
-    private String contractType;
+    private Long contractType;
 
     /**
      * 合同名称
@@ -98,7 +99,7 @@ public class SupplierContractVo implements Serializable {
     /**
      * 合同数
      */
-    private String ContractNum;
+    private String contractNum;
 
     /**
      * 有效期内的合同
@@ -109,9 +110,4 @@ public class SupplierContractVo implements Serializable {
      */
     private String invalidContract;
 
-
-
-
-
-
 }

+ 3 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierInfoVo.java

@@ -400,4 +400,7 @@ public class SupplierInfoVo implements Serializable {
     private Long cooperative;
 
 
+    private Date createTime;
+
+
 }

+ 81 - 11
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierInformationVo.java

@@ -66,6 +66,80 @@ public class SupplierInformationVo implements Serializable {
     @ExcelProperty(value = "合作类型")
     private String cooperationType;
 
+    /**
+     * 工商名称
+     */
+    private String businessName;
+
+    /**
+     * 企业简称
+     */
+    private String shortName;
+
+    /**
+     * 办公地址-省
+     */
+    private String officeProvince;
+
+    /**
+     * 办公地址-市
+     */
+    private String officeCity;
+
+    /**
+     * 办公地址-区/县
+     */
+    private String officeCounty;
+
+    /**
+     * 办公详细地址
+     */
+    private String officeAddress;
+
+    /**
+     * 开始时间
+     */
+    @ExcelProperty(value = "有效期开始时间")
+    private Date validityFromDate;
+
+    /**
+     * 结束时间
+     */
+    @ExcelProperty(value = "有效期结束时间")
+    private Date validityToDate;
+
+    /**
+     * 固定电话
+     */
+    @ExcelProperty(value = "固定电话")
+    private String fixedPhone;
+
+    /**
+     * 传真
+     */
+    @ExcelProperty(value = "传真")
+    private String fax;
+
+    /**
+     * 邮箱
+     */
+    @ExcelProperty(value = "邮箱")
+    private String mailbox;
+
+    /**
+     * 邮政编码
+     */
+    @ExcelProperty(value = "邮政编码")
+    private String postCode;
+
+    /**
+     * 网址
+     */
+    @ExcelProperty(value = "网址")
+    private String url;
+
+
+
     /**
      * 供货范围
      */
@@ -134,17 +208,6 @@ public class SupplierInformationVo implements Serializable {
     private Long pushStatus;
 
 
-    /**
-     * 有效期开始时间
-     */
-    @ExcelProperty(value = "有效期开始时间")
-    private Date validityFromDate;
-
-    /**
-     * 有效期结束时间
-     */
-    @ExcelProperty(value = "有效期结束时间")
-    private Date validityToDate;
 
 
     /**
@@ -177,5 +240,12 @@ public class SupplierInformationVo implements Serializable {
 
     private Map<String,Object> otherCustomersMap;
 
+    private Date createTime;
+
+    /**
+     * 上架产品数
+     */
+    private Long listedNum = 0L;
+
 
 }

+ 51 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/enums/ContractSupplierStatusEnum.java

@@ -0,0 +1,51 @@
+package org.dromara.customer.enums;
+
+/**
+ * author
+ * 时间:2026/1/19,0:22
+ */
+public enum ContractSupplierStatusEnum {
+    // 枚举项:状态码, 展示文案
+    UNEFFECTIVE(0, "未生效"),
+    EFFECTIVE(1, "已生效"),
+    EXPIRED(2, "已过期");
+
+    // 状态码
+    private final Integer code;
+    // 前端/业务展示的文案
+    private final String displayName;
+
+    // 修正构造方法名称(必须和枚举类名一致)
+    ContractSupplierStatusEnum(Integer code, String displayName) {
+        this.code = code;
+        this.displayName = displayName;
+    }
+
+    /**
+     * 核心方法:根据状态码获取展示文案
+     * @param code 数据库中的数字值(0/1/2)
+     * @return 展示文案,无匹配时返回"未知状态"
+     */
+    public static String getDisplayNameByCode(Integer code) {
+        // 空值校验,避免空指针
+        if (code == null) {
+            return "未知状态";
+        }
+        // 遍历枚举匹配状态码(修正枚举类型为当前类)
+        for (ContractSupplierStatusEnum status : values()) {
+            if (status.code.equals(code)) {
+                return status.displayName;
+            }
+        }
+        return "未知状态";
+    }
+
+    // getter方法(便于单独获取码值/文案)
+    public Integer getCode() {
+        return code;
+    }
+
+    public String getDisplayName() {
+        return displayName;
+    }
+}

+ 15 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/SupplierAddressMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.customer.mapper;
+
+import org.dromara.customer.domain.SupplierAddress;
+import org.dromara.customer.domain.vo.SupplierAddressVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 供应商地址Mapper接口
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+public interface SupplierAddressMapper extends BaseMapperPlus<SupplierAddress, SupplierAddressVo> {
+
+}

+ 72 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierAddressService.java

@@ -0,0 +1,72 @@
+package org.dromara.customer.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.customer.domain.SupplierAddress;
+import org.dromara.customer.domain.vo.SupplierAddressVo;
+import org.dromara.customer.domain.bo.SupplierAddressBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 供应商地址Service接口
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+public interface ISupplierAddressService extends IService<SupplierAddress>{
+
+    /**
+     * 查询供应商地址
+     *
+     * @param id 主键
+     * @return 供应商地址
+     */
+    SupplierAddressVo queryById(Long id);
+
+    /**
+     * 分页查询供应商地址列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 供应商地址分页列表
+     */
+    TableDataInfo<SupplierAddressVo> queryPageList(SupplierAddressBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的供应商地址列表
+     *
+     * @param bo 查询条件
+     * @return 供应商地址列表
+     */
+    List<SupplierAddressVo> queryList(SupplierAddressBo bo);
+
+    /**
+     * 新增供应商地址
+     *
+     * @param bo 供应商地址
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(SupplierAddressBo bo);
+
+    /**
+     * 修改供应商地址
+     *
+     * @param bo 供应商地址
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(SupplierAddressBo bo);
+
+    /**
+     * 校验并批量删除供应商地址信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    List<SupplierAddressVo> getSupplierAddressById(SupplierAddressBo bo);
+}

+ 91 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/ContractSupplyServiceImpl.java

@@ -1,7 +1,9 @@
 package org.dromara.customer.service.impl;
 
+import cn.hutool.core.date.DateUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.ObjectUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
@@ -10,6 +12,10 @@ 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.domain.SupplierInfo;
+import org.dromara.customer.domain.vo.SupplierContractVo;
+import org.dromara.customer.enums.ContractSupplierStatusEnum;
+import org.dromara.customer.service.ISupplierInfoService;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.ContractSupplyBo;
 import org.dromara.customer.domain.vo.ContractSupplyVo;
@@ -17,9 +23,8 @@ import org.dromara.customer.domain.ContractSupply;
 import org.dromara.customer.mapper.ContractSupplyMapper;
 import org.dromara.customer.service.IContractSupplyService;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 协议供货Service业务层处理
@@ -34,6 +39,8 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
 
     private final ContractSupplyMapper baseMapper;
 
+    private final ISupplierInfoService supplierInfoService;
+
     /**
      * 查询协议供货
      *
@@ -56,9 +63,90 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
     public TableDataInfo<ContractSupplyVo> queryPageList(ContractSupplyBo bo, PageQuery pageQuery) {
         LambdaQueryWrapper<ContractSupply> lqw = buildQueryWrapper(bo);
         Page<ContractSupplyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        setSupplierNames(result.getRecords());
+        // 2处理状态和剩余时限
+        handleStatusAndRemainingTime(result.getRecords());
         return TableDataInfo.build(result);
     }
 
+    /**
+     * 处理状态文案(替换为枚举展示名)和剩余时限计算
+     * @param records 分页查询结果列表
+     */
+    private void handleStatusAndRemainingTime(List<ContractSupplyVo> records) {
+        if (ObjectUtils.isEmpty(records)) {
+            return;
+        }
+        Date now = new Date(); // 获取当前时间,避免循环内重复创建
+        for (ContractSupplyVo vo : records) {
+            // ========== 1. 状态值替换为枚举展示文案 ==========
+            String statusCode = vo.getStatus();
+            if (statusCode != null) {
+                // 将字符串类型的status转为Integer,匹配枚举的code
+                try {
+                    Integer code = Integer.parseInt(statusCode);
+                    // 调用枚举方法获取展示文案
+                    String displayName = ContractSupplierStatusEnum.getDisplayNameByCode(code);
+                    vo.setStatus(displayName); // 替换为展示文案
+                } catch (NumberFormatException e) {
+                    // 非数字类型的status,设置为"未知状态"
+                    vo.setStatus("");
+                }
+            } else {
+                // status为空时,设置为"未知状态"
+                vo.setStatus("");
+            }
+
+            // ========== 2. 计算剩余时限(天) ==========
+            Date endTime = vo.getEndTime();
+            if (endTime != null) {
+                long diff = endTime.getTime() - now.getTime();
+                long days = diff / (1000 * 60 * 60 * 24);
+                if (days >= 0) {
+                    vo.setTimeRemaining(days + "天");
+                } else {
+                    vo.setTimeRemaining("0天");
+                }
+            } else {
+                vo.setTimeRemaining("0" + "天");
+            }
+        }
+    }
+
+    private void setSupplierNames(List<ContractSupplyVo> records) {
+        if (records == null || records.isEmpty()) {
+            return;
+        }
+
+        // 提取供应商ID列表
+        List<Long> supplierIds = records.stream()
+            .map(ContractSupplyVo::getSupplierId)
+            .filter(Objects::nonNull)
+            .distinct()
+            .collect(Collectors.toList());
+
+        if (!supplierIds.isEmpty()) {
+            // 查询供应商名称
+            List<SupplierInfo> supplierInfos = supplierInfoService.lambdaQuery()
+                .in(SupplierInfo::getId, supplierIds)
+                .select(SupplierInfo::getId, SupplierInfo::getEnterpriseName)
+                .list();
+
+            // 构建映射关系
+            Map<Long, String> supplierNameMap = supplierInfos.stream()
+                .collect(Collectors.toMap(
+                    SupplierInfo::getId,
+                    SupplierInfo::getEnterpriseName
+                ));
+
+            // 设置供应商名称
+            records.forEach(record -> {
+                String supplierName = supplierNameMap.get(record.getSupplierId());
+                record.setSupplierName(supplierName);
+            });
+        }
+    }
+
     /**
      * 查询符合条件的协议供货列表
      *

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

@@ -73,8 +73,10 @@ public class EnterpriseScaleServiceImpl extends ServiceImpl<EnterpriseScaleMappe
     public List<EnterpriseScaleVo> queryList(EnterpriseScaleBo bo) {
         LambdaQueryWrapper<EnterpriseScale> lqw = buildQueryWrapper(bo);
         return baseMapper.selectVoList(lqw);
+
     }
 
+
     private LambdaQueryWrapper<EnterpriseScale> buildQueryWrapper(EnterpriseScaleBo bo) {
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<EnterpriseScale> lqw = Wrappers.lambdaQuery();

+ 152 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAddressServiceImpl.java

@@ -0,0 +1,152 @@
+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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.customer.domain.bo.SupplierAddressBo;
+import org.dromara.customer.domain.vo.SupplierAddressVo;
+import org.dromara.customer.domain.SupplierAddress;
+import org.dromara.customer.mapper.SupplierAddressMapper;
+import org.dromara.customer.service.ISupplierAddressService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 供应商地址Service业务层处理
+ *
+ * @author LJY
+ * @date 2026-01-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class SupplierAddressServiceImpl  extends ServiceImpl<SupplierAddressMapper, SupplierAddress> implements ISupplierAddressService {
+
+    private final SupplierAddressMapper baseMapper;
+
+    /**
+     * 查询供应商地址
+     *
+     * @param id 主键
+     * @return 供应商地址
+     */
+    @Override
+    public SupplierAddressVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询供应商地址列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 供应商地址分页列表
+     */
+    @Override
+    public TableDataInfo<SupplierAddressVo> queryPageList(SupplierAddressBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SupplierAddress> lqw = buildQueryWrapper(bo);
+        Page<SupplierAddressVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的供应商地址列表
+     *
+     * @param bo 查询条件
+     * @return 供应商地址列表
+     */
+    @Override
+    public List<SupplierAddressVo> queryList(SupplierAddressBo bo) {
+        LambdaQueryWrapper<SupplierAddress> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SupplierAddress> buildQueryWrapper(SupplierAddressBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SupplierAddress> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(SupplierAddress::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getSupplierNo()), SupplierAddress::getSupplierNo, bo.getSupplierNo());
+        lqw.eq(bo.getSupplierId() != null, SupplierAddress::getSupplierId, bo.getSupplierId());
+        lqw.eq(StringUtils.isNotBlank(bo.getShippingCompany()), SupplierAddress::getShippingCompany, bo.getShippingCompany());
+        lqw.like(StringUtils.isNotBlank(bo.getShipperName()), SupplierAddress::getShipperName, bo.getShipperName());
+        lqw.eq(StringUtils.isNotBlank(bo.getShipperPhone()), SupplierAddress::getShipperPhone, bo.getShipperPhone());
+        lqw.eq(StringUtils.isNotBlank(bo.getShippingPostCode()), SupplierAddress::getShippingPostCode, bo.getShippingPostCode());
+        lqw.eq(StringUtils.isNotBlank(bo.getShippingProvincial()), SupplierAddress::getShippingProvincial, bo.getShippingProvincial());
+        lqw.eq(StringUtils.isNotBlank(bo.getShippingCity()), SupplierAddress::getShippingCity, bo.getShippingCity());
+        lqw.eq(StringUtils.isNotBlank(bo.getShippingCounty()), SupplierAddress::getShippingCounty, bo.getShippingCounty());
+        lqw.eq(StringUtils.isNotBlank(bo.getShippingAddress()), SupplierAddress::getShippingAddress, bo.getShippingAddress());
+        lqw.eq(StringUtils.isNotBlank(bo.getPushStatus()), SupplierAddress::getPushStatus, bo.getPushStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getIsSelf()), SupplierAddress::getIsSelf, bo.getIsSelf());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), SupplierAddress::getType, bo.getType());
+        lqw.eq(StringUtils.isNotBlank(bo.getAddressNo()), SupplierAddress::getAddressNo, bo.getAddressNo());
+        return lqw;
+    }
+
+    /**
+     * 新增供应商地址
+     *
+     * @param bo 供应商地址
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(SupplierAddressBo bo) {
+        SupplierAddress add = MapstructUtils.convert(bo, SupplierAddress.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改供应商地址
+     *
+     * @param bo 供应商地址
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(SupplierAddressBo bo) {
+        SupplierAddress update = MapstructUtils.convert(bo, SupplierAddress.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(SupplierAddress entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除供应商地址信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    @Override
+    public List<SupplierAddressVo> getSupplierAddressById(SupplierAddressBo bo) {
+        LambdaQueryWrapper<SupplierAddress> supplierAddressLambdaQueryWrapper = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(supplierAddressLambdaQueryWrapper);
+    }
+}

+ 100 - 12
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAuthorizeServiceImpl.java

@@ -13,6 +13,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.customer.domain.SupplierInfo;
+import org.dromara.customer.domain.SupplyArea;
 import org.dromara.customer.domain.vo.SupplierContractVo;
 import org.dromara.customer.domain.vo.SupplyAreaVo;
 import org.dromara.customer.service.ISupplierInfoService;
@@ -89,10 +90,70 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
     @Override
     public TableDataInfo<SupplierAuthorizeVo> getSupplyCapacityList(SupplierAuthorizeBo bo, PageQuery pageQuery) {
         //查询供应商信息
-        IPage<SupplierInfo> result =supplierInfoService.getSupplyCapacityList(bo,pageQuery);
+        IPage<SupplierInfo> result = supplierInfoService.getSupplyCapacityList(bo, pageQuery);
         List<SupplierInfo> records = result.getRecords();
-        Map<Long,String> supplierCategoryMap = records.stream().collect(Collectors.toMap(SupplierInfo::getId, SupplierInfo::getOperatingCategory));
+        Map<Long, String> supplierCategoryMap = records.stream().collect(Collectors.toMap(SupplierInfo::getId, SupplierInfo::getOperatingCategory));
+        //查询供应品类
+        Map<Long, String> supplierCategoryNameMap = supplierCategoryNamesMap(supplierCategoryMap);
+        //查询授权品牌String拼接
+        List<Long> ids = records.stream().map(item -> item.getId()).collect(Collectors.toList());
+        Map<Long, String> supplierBrandMap = supplierBrandMap(ids);
+
+        List<SupplierAuthorizeVo> collect = result.getRecords().stream().map(item -> {
+            SupplierAuthorizeVo supplierAuthorizeVo = new SupplierAuthorizeVo();
+            BeanUtils.copyProperties(item, supplierAuthorizeVo);
+            supplierAuthorizeVo.setSupplierName(item.getEnterpriseName());
+            supplierAuthorizeVo.setSupplyBrand(item.getOperatingBrand());
+            supplierAuthorizeVo.setSupplyProCate(supplierCategoryNameMap.get(item.getId()));
+            supplierAuthorizeVo.setAuthBrand(supplierBrandMap.get(item.getId()));
+            return supplierAuthorizeVo;
+        }).collect(Collectors.toList());
+        IPage<SupplierAuthorizeVo> voPage = new Page<>();
+        BeanUtils.copyProperties(result, voPage);
+        // 设置转换后的Vo列表
+        voPage.setRecords(collect);
+        return TableDataInfo.build(voPage);
+
+    }
+
+    private Map<Long, String> supplierBrandMap(List<Long> ids){
+        List<SupplierAuthorize> authorizeList = baseMapper.selectList(
+            new LambdaQueryWrapper<SupplierAuthorize>()
+                .in(SupplierAuthorize::getSupplierId, ids) // 批量查询指定供应商的授权记录
+                .select(SupplierAuthorize::getSupplierId, SupplierAuthorize::getBrandName) // 只查需要的字段
+        );
+
+        // 3. 先按供应商ID分组,再对品牌名称去重(核心:用Set去重)
+        Map<Long, Set<String>> supplierBrandSetMap = authorizeList.stream()
+            .filter(auth -> {
+                // 过滤无效数据:供应商ID为空 或 品牌名称为空/空白
+                return auth.getSupplierId() != null && StringUtils.isNotBlank(auth.getBrandName());
+            })
+            // 分组:key=供应商ID,value=该供应商的所有品牌名称(Set自动去重)
+            .collect(Collectors.groupingBy(
+                SupplierAuthorize::getSupplierId,
+                Collectors.mapping(
+                    SupplierAuthorize::getBrandName,
+                    Collectors.toSet() // Set保证品牌名称不重复
+                )
+            ));
+        // 4. 将Set转换为拼接的字符串,生成最终Map
+        Map<Long, String> supplierBrandMap = new HashMap<>();
+        // 遍历所有供应商ID(确保即使无授权品牌也有记录,值为空字符串)
+        for (Long supplierId : ids) {
+            Set<String> brandSet = supplierBrandSetMap.getOrDefault(supplierId, new HashSet<>());
+            // 拼接Set中的品牌名称(用英文逗号分隔,可改为中文逗号“,”)
+            String brandStr = String.join(",", brandSet);
+            supplierBrandMap.put(supplierId, brandStr);
+        }
 
+        return supplierBrandMap;
+    }
+
+
+
+
+    private Map<Long, String> supplierCategoryNamesMap(Map<Long, String> supplierCategoryMap) {
         Set<Long> allCategoryIds = new HashSet<>();
         for (String categoryIdStr : supplierCategoryMap.values()) {
             // 拆分品类ID字符串(如"1,2,3" → ["1","2","3"])
@@ -111,20 +172,45 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
         // 2. 批量查询品类ID→名称的映射
         Map<Long, String> categoryIdToNameMap = new HashMap<>();
         if (!allCategoryIds.isEmpty()) {
-            Map<Long, String> categoryNamebyIds = remoteCategoryService.getCategoryNamebyIds(allCategoryIds);
+            categoryIdToNameMap = remoteCategoryService.getCategoryNamebyIds(allCategoryIds);
         }
 
-        /*result.getRecords().stream().map(item -> {
-            SupplierAuthorizeVo supplierAuthorizeVo = new SupplierAuthorizeVo();
-            BeanUtils.copyProperties(item, supplierAuthorizeVo);
-            supplierAuthorizeVo.setSupplierName(item.getSupplierName());
-
-        }).collect(Collectors.toList());*/
+        // 3. 转换supplierCategoryMap为“供应商ID→拼接的品类名称”
+        Map<Long, String> supplierCategoryNameMap = new HashMap<>();
+        for (Map.Entry<Long, String> entry : supplierCategoryMap.entrySet()) {
+            Long supplierId = entry.getKey(); // 供应商ID
+            String categoryIdStr = entry.getValue(); // 品类ID字符串(如"1,2,3")
 
-        //supplierInfoService
+            // 处理空值:无品类ID则存空字符串
+            if (!StringUtils.isNotBlank(categoryIdStr)) {
+                supplierCategoryNameMap.put(supplierId, "");
+                continue;
+            }
 
-        return null;
+            // 拆分品类ID并拼接名称
+            StringBuilder nameBuilder = new StringBuilder();
+            String[] idArr = categoryIdStr.split(",");
+            for (String idStr : idArr) {
+                try {
+                    Long categoryId = Long.parseLong(idStr.trim());
+                    // 获取品类名称(无匹配则用空字符串兜底)
+                    String categoryName = categoryIdToNameMap.getOrDefault(categoryId, "");
+                    // 非空名称才拼接,避免多余分隔符
+                    if (StringUtils.isNotBlank(categoryName)) {
+                        if (nameBuilder.length() > 0) {
+                            nameBuilder.append(","); // 分隔符可改为中文逗号“,”
+                        }
+                        nameBuilder.append(categoryName);
+                    }
+                } catch (NumberFormatException e) {
+                    continue;
+                }
+            }
+            // 将拼接结果存入新Map
+            supplierCategoryNameMap.put(supplierId, nameBuilder.toString());
 
+        }
+        return supplierCategoryNameMap;
     }
 
     private LambdaQueryWrapper<SupplierAuthorize> buildQueryWrapper(SupplierAuthorizeBo bo) {
@@ -220,7 +306,9 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
             supplierAuthorizeVos.stream().filter(item -> item.getId().equals(id)).forEach(item -> item.setCity(city));
         });
         //一级 二级 三级 品目
-        Map<Long,Long> categoryMap = supplierAuthorizeVos.stream().collect(Collectors.toMap(
+        Map<Long,Long> categoryMap = supplierAuthorizeVos.stream()
+            .filter(item -> item.getId() != null && item.getCategoryId() != null)
+            .collect(Collectors.toMap(
             SupplierAuthorizeVo::getId,
             item ->item.getCategoryId()
         ));

+ 62 - 18
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContractServiceImpl.java

@@ -12,6 +12,7 @@ import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.customer.domain.SupplierInfo;
+import org.dromara.customer.domain.dto.ContractCountDTO;
 import org.dromara.customer.domain.vo.SupplierContactVo;
 import org.dromara.customer.service.ISupplierInfoService;
 import org.springframework.stereotype.Service;
@@ -21,10 +22,7 @@ import org.dromara.customer.domain.SupplierContract;
 import org.dromara.customer.mapper.SupplierContractMapper;
 import org.dromara.customer.service.ISupplierContractService;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
-import java.util.Objects;
+import java.util.*;
 import java.util.stream.Collectors;
 
 /**
@@ -62,31 +60,70 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
      */
     @Override
     public TableDataInfo<SupplierContractVo> queryPageList(SupplierContractBo bo, PageQuery pageQuery) {
+        if (bo.getSupplierName() != null){
+            SupplierInfo one = supplierInfoService.getOne(new LambdaQueryWrapper<SupplierInfo>().eq(SupplierInfo::getEnterpriseName, bo.getSupplierName()));
+            bo.setSupplierId(one.getId());
+        }
         LambdaQueryWrapper<SupplierContract> lqw = buildQueryWrapper(bo);
-
         // 查询所有符合条件的记录
         List<SupplierContract> allRecords = baseMapper.selectList(lqw);
+        // 获取当前时间(用于判断合同是否过期)
+        Date now = new Date();
 
-        List<SupplierContractVo> contractStats = allRecords.stream().collect(Collectors.groupingBy(
+        // 按供应商ID分组,同时统计总数、有效数、失效数
+        Map<Long, ContractCountDTO> countMap = allRecords.stream()
+            .collect(Collectors.groupingBy(
                 SupplierContract::getSupplierId,
-                Collectors.counting()
-            ))
-            .entrySet().stream().map(entry -> {
+                Collectors.collectingAndThen(
+                    Collectors.toList(),
+                    list -> {
+                        // 统计总数
+                        long total = list.size();
+                        // 统计有效期内合同数
+                        long validCount = list.stream()
+                            .filter(contract ->
+                                // 状态为已生效 且 到期时间晚于当前时间
+                                1L == (contract.getContractStatus())
+                                    && contract.getContractEndTime().after(now)
+                            ).count();
+                        // 统计失效合同数(总数 - 有效数)
+                        long invalidCount = total - validCount;
+                        return new ContractCountDTO(total, validCount, invalidCount);
+                    }
+                )
+            ));
+
+        // 转换为VO列表并排序
+        List<SupplierContractVo> contractStats = countMap.entrySet().stream()
+            .map(entry -> {
+                Long supplierId = entry.getKey();
+                ContractCountDTO countDTO = entry.getValue();
+
                 SupplierContractVo vo = new SupplierContractVo();
-                vo.setSupplierId(entry.getKey());
-                vo.setContractNum(entry.getValue().toString());
-                SupplierInfo supplier = supplierInfoService.getById(entry.getKey());
-                vo.setSupplierName(supplier.getSupplierName());
-                vo.setSupplierNo(supplier.getSupplierNo());
+                vo.setSupplierId(supplierId);
+                // 合同总数
+                vo.setContractNum(String.valueOf(countDTO.getTotal()));
+                // 有效期内合同数
+                vo.setValidContract(String.valueOf(countDTO.getValidCount()));
+                // 失效合同数
+                vo.setInvalidContract(String.valueOf(countDTO.getInvalidCount()));
+
+                // 查询供应商基本信息
+                SupplierInfo supplier = supplierInfoService.getById(supplierId);
+                if (supplier != null) { // 增加空指针防护
+                    vo.setSupplierName(supplier.getEnterpriseName());
+                    vo.setSupplierNo(supplier.getSupplierNo());
+                }
                 return vo;
             })
-            .sorted((a,b) ->b.getSupplierNo().compareTo(a.getSupplierNo()))
+            .sorted((a, b) -> b.getSupplierNo().compareTo(a.getSupplierNo()))
             .collect(Collectors.toList());
 
+        // 分页处理
         int total = contractStats.size();
-        int start = (int)((pageQuery.getPageNum()-1) * pageQuery.getPageSize());
-        int end = Math.min(start + pageQuery.getPageSize(),total);
-        List<SupplierContractVo> pagedResult = contractStats.subList(start, end);
+        int start = (int) ((pageQuery.getPageNum() - 1) * pageQuery.getPageSize());
+        int end = Math.min(start + pageQuery.getPageSize(), total);
+        List<SupplierContractVo> pagedResult = start > end ? List.of() : contractStats.subList(start, end);
 
         Page<SupplierContractVo> result = new Page<>();
         result.setRecords(pagedResult);
@@ -154,7 +191,13 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
         Map<String, Object> params = bo.getParams();
         LambdaQueryWrapper<SupplierContract> lqw = Wrappers.lambdaQuery();
         lqw.orderByDesc(SupplierContract::getSupplierNo);
+        lqw.like(StringUtils.isNotBlank(bo.getContractNo()), SupplierContract::getContractNo, bo.getContractNo());
+        lqw.like(StringUtils.isNotBlank(bo.getContractName()), SupplierContract::getContractName, bo.getSupplierName());
         lqw.eq(StringUtils.isNotBlank(bo.getSupplierNo()), SupplierContract::getSupplierNo, bo.getSupplierNo());
+        lqw.eq(bo.getContractStatus()!=null, SupplierContract::getContractStatus, bo.getContractStatus());
+        lqw.gt(bo.getContractStartTime() !=null, SupplierContract::getContractStartTime, bo.getContractStartTime());
+        lqw.lt(bo.getContractEndTime() !=null, SupplierContract::getContractEndTime, bo.getContractEndTime());
+        lqw.eq(bo.getContractStatus() != null, SupplierContract::getContractStatus, bo.getContractStatus());
         lqw.eq(bo.getSupplierId() != null && !bo.getSupplierId().equals(""),SupplierContract::getSupplierId, bo.getSupplierId());
         return lqw;
     }
@@ -169,6 +212,7 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
     public Boolean insertByBo(SupplierContractBo bo) {
         SupplierContract add = MapstructUtils.convert(bo, SupplierContract.class);
         validEntityBeforeSave(add);
+        add.setContractStatus(0L);
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
 //            bo.setId(add.getId());

+ 128 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java

@@ -19,6 +19,8 @@ import org.dromara.customer.domain.bo.SupplierAuthorizeBo;
 import org.dromara.customer.domain.vo.SupplierInformationVo;
 import org.dromara.customer.service.ISupplierProcurementService;
 import org.dromara.customer.service.ISupplyAreaService;
+import org.dromara.product.api.RemoteCategoryService;
+import org.dromara.product.api.RemoteProductService;
 import org.dromara.system.api.RemoteComStaffService;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
@@ -27,6 +29,7 @@ import org.dromara.customer.domain.vo.SupplierInfoVo;
 import org.dromara.customer.domain.SupplierInfo;
 import org.dromara.customer.mapper.SupplierInfoMapper;
 import org.dromara.customer.service.ISupplierInfoService;
+import org.springframework.util.CollectionUtils;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -50,6 +53,8 @@ public class SupplierInfoServiceImpl  extends ServiceImpl<SupplierInfoMapper, Su
 
     private final RemoteComStaffService remoteComStaffService;
 
+    private final RemoteCategoryService remoteCategoryService;
+
     /**
      * 查询供应商信息
      *
@@ -102,6 +107,7 @@ public class SupplierInfoServiceImpl  extends ServiceImpl<SupplierInfoMapper, Su
         targetVo.setProvince(provinceNames);
         targetVo.setCity(cityNames);
 
+
         return targetVo;
     }
 
@@ -186,6 +192,13 @@ public class SupplierInfoServiceImpl  extends ServiceImpl<SupplierInfoMapper, Su
                 return targetVo;
             })
             .collect(Collectors.toList());
+        //获取供应类别
+        Map<Long, String> supplierCategoryMap = supplierInformationVos.stream().collect(Collectors.toMap(SupplierInformationVo::getId, SupplierInformationVo::getOperatingCategory));
+        //查询供应品类
+        Map<Long, String> supplierCategoryNameMap = supplierCategoryNamesMap(supplierCategoryMap);
+        supplierInformationVos.forEach(vo -> {
+            vo.setOperatingCategory(supplierCategoryNameMap.get(vo.getId()));
+        });
         for (SupplierInformationVo vo : supplierInformationVos) {
             // 查询管理人员和采购人员
             Long id = vo.getId();
@@ -235,6 +248,66 @@ public class SupplierInfoServiceImpl  extends ServiceImpl<SupplierInfoMapper, Su
         return supplierInformationVos;
     }
 
+    private Map<Long, String> supplierCategoryNamesMap(Map<Long, String> supplierCategoryMap) {
+        Set<Long> allCategoryIds = new HashSet<>();
+        for (String categoryIdStr : supplierCategoryMap.values()) {
+            // 拆分品类ID字符串(如"1,2,3" → ["1","2","3"])
+            String[] idArr = categoryIdStr.split(",");
+            for (String idStr : idArr) {
+                try {
+                    Long categoryId = Long.parseLong(idStr.trim()); // 去除空格,避免格式问题
+                    allCategoryIds.add(categoryId);
+                } catch (NumberFormatException e) {
+                    // 异常处理:ID格式错误时跳过,不影响整体逻辑
+                    continue;
+                }
+            }
+        }
+
+        // 2. 批量查询品类ID→名称的映射
+        Map<Long, String> categoryIdToNameMap = new HashMap<>();
+        if (!allCategoryIds.isEmpty()) {
+            categoryIdToNameMap = remoteCategoryService.getCategoryNamebyIds(allCategoryIds);
+        }
+
+        // 3. 转换supplierCategoryMap为“供应商ID→拼接的品类名称”
+        Map<Long, String> supplierCategoryNameMap = new HashMap<>();
+        for (Map.Entry<Long, String> entry : supplierCategoryMap.entrySet()) {
+            Long supplierId = entry.getKey(); // 供应商ID
+            String categoryIdStr = entry.getValue(); // 品类ID字符串(如"1,2,3")
+
+            // 处理空值:无品类ID则存空字符串
+            if (!StringUtils.isNotBlank(categoryIdStr)) {
+                supplierCategoryNameMap.put(supplierId, "");
+                continue;
+            }
+
+            // 拆分品类ID并拼接名称
+            StringBuilder nameBuilder = new StringBuilder();
+            String[] idArr = categoryIdStr.split(",");
+            for (String idStr : idArr) {
+                try {
+                    Long categoryId = Long.parseLong(idStr.trim());
+                    // 获取品类名称(无匹配则用空字符串兜底)
+                    String categoryName = categoryIdToNameMap.getOrDefault(categoryId, "");
+                    // 非空名称才拼接,避免多余分隔符
+                    if (StringUtils.isNotBlank(categoryName)) {
+                        if (nameBuilder.length() > 0) {
+                            nameBuilder.append(","); // 分隔符可改为中文逗号“,”
+                        }
+                        nameBuilder.append(categoryName);
+                    }
+                } catch (NumberFormatException e) {
+                    continue;
+                }
+            }
+            // 将拼接结果存入新Map
+            supplierCategoryNameMap.put(supplierId, nameBuilder.toString());
+
+        }
+        return supplierCategoryNameMap;
+    }
+
     /**
      * 查询符合条件的供应商信息列表
      *
@@ -301,8 +374,6 @@ public class SupplierInfoServiceImpl  extends ServiceImpl<SupplierInfoMapper, Su
         lqw.eq(StringUtils.isNotBlank(bo.getType()), SupplierInfo::getType, bo.getType());
         lqw.eq(StringUtils.isNotBlank(bo.getOwnedCompany()), SupplierInfo::getOwnedCompany, bo.getOwnedCompany());
         lqw.eq(bo.getPushStatus() != null, SupplierInfo::getPushStatus, bo.getPushStatus());
-        lqw.eq(bo.getCreated() != null, SupplierInfo::getCreated, bo.getCreated());
-        lqw.eq(bo.getModify() != null, SupplierInfo::getModify, bo.getModify());
         lqw.eq(bo.getValidityFromDate() != null, SupplierInfo::getValidityFromDate, bo.getValidityFromDate());
         lqw.eq(bo.getValidityToDate() != null, SupplierInfo::getValidityToDate, bo.getValidityToDate());
         lqw.eq(bo.getRowNo() != null, SupplierInfo::getRowNo, bo.getRowNo());
@@ -375,6 +446,61 @@ public class SupplierInfoServiceImpl  extends ServiceImpl<SupplierInfoMapper, Su
         IPage<SupplierInfo> page = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
 
         IPage<SupplierInfo> resultPage = baseMapper.selectPage(page, lqw);
+        List<SupplierInfo> records = resultPage.getRecords();
+        // 3. 批量处理省份/城市名称(核心优化:批量查库,避免循环查)
+        if (!CollectionUtils.isEmpty(records)) {
+            // 3.1 提取所有供应商ID
+            Set<Long> supplierIds = records.stream()
+                .map(SupplierInfo::getId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            if (!supplierIds.isEmpty()) {
+                // 3.2 批量查询所有供应商的省级(level=1)和市级(level=2)地址
+                LambdaQueryWrapper<SupplyArea> areaLqw = Wrappers.lambdaQuery();
+                areaLqw.in(SupplyArea::getSupplierId, supplierIds)
+                    .in(SupplyArea::getLevel, "1", "2") // 同时查省级和市级
+                    .select(SupplyArea::getSupplierId, SupplyArea::getLevel, SupplyArea::getAreaName);
+
+                List<SupplyArea> allSupplyAreas = supplyAreaService.list(areaLqw);
+
+                // 3.3 按【供应商ID+级别】分组,方便快速匹配
+                // key: 供应商ID + "_" + 级别(如 "1001_1"),value: 该级别下的名称列表
+                Map<String, List<String>> areaGroupMap = allSupplyAreas.stream()
+                    .filter(area -> {
+                        // 过滤无效数据
+                        return area.getSupplierId() != null
+                            && StringUtils.isNotBlank(area.getLevel())
+                            && StringUtils.isNotBlank(area.getAreaName());
+                    })
+                    .collect(Collectors.groupingBy(
+                        // 分组key:供应商ID_级别
+                        area -> area.getSupplierId() + "_" + area.getLevel(),
+                        // 收集该分组下的所有区域名称
+                        Collectors.mapping(SupplyArea::getAreaName, Collectors.toList())
+                    ));
+
+                // 3.4 给每个SupplierInfo设置省份/城市名称
+                for (SupplierInfo item : records) {
+                    Long id = item.getId();
+                    if (id == null) {
+                        item.setProvince("");
+                        item.setCity("");
+                        continue;
+                    }
+
+                    // 获取省级名称(level=1)
+                    List<String> provinceNames = areaGroupMap.getOrDefault(id + "_1", new ArrayList<>());
+                    String provinceStr = provinceNames.stream().collect(Collectors.joining(","));
+                    item.setProvince(provinceStr);
+
+                    // 获取市级名称(level=2)
+                    List<String> cityNames = areaGroupMap.getOrDefault(id + "_2", new ArrayList<>());
+                    String cityStr = cityNames.stream().collect(Collectors.joining(","));
+                    item.setCity(cityStr);
+                }
+            }
+        }
 
         return resultPage;
     }

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SupplierAddressMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.customer.mapper.SupplierAddressMapper">
+
+</mapper>

+ 1 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteCategoryServiceImpl.java

@@ -7,6 +7,7 @@ import org.dromara.product.api.RemoteCategoryService;
 import org.dromara.product.domain.ProductCategory;
 import org.dromara.product.mapper.ProductCategoryMapper;
 import org.springframework.stereotype.Service;
+import org.springframework.util.StringUtils;
 
 import java.util.*;
 import java.util.stream.Collectors;

+ 106 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/ProductTaxrateController.java

@@ -0,0 +1,106 @@
+package org.dromara.system.controller.system;
+
+import java.util.List;
+
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.web.bind.annotation.*;
+import org.springframework.validation.annotation.Validated;
+import org.dromara.common.idempotent.annotation.RepeatSubmit;
+import org.dromara.common.log.annotation.Log;
+import org.dromara.common.web.core.BaseController;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import org.dromara.common.log.enums.BusinessType;
+import org.dromara.common.excel.utils.ExcelUtil;
+import org.dromara.system.domain.vo.ProductTaxrateVo;
+import org.dromara.system.domain.bo.ProductTaxrateBo;
+import org.dromara.system.service.IProductTaxrateService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 产品税率配置
+ * 前端访问路由地址为:/system/taxrate
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/taxrate")
+public class ProductTaxrateController extends BaseController {
+
+    private final IProductTaxrateService productTaxrateService;
+
+    /**
+     * 查询产品税率配置列表
+     */
+    //@SaCheckPermission("system:taxrate:list")
+    @GetMapping("/list")
+    public TableDataInfo<ProductTaxrateVo> list(ProductTaxrateBo bo, PageQuery pageQuery) {
+        return productTaxrateService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出产品税率配置列表
+     */
+    @SaCheckPermission("system:taxrate:export")
+    @Log(title = "产品税率配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ProductTaxrateBo bo, HttpServletResponse response) {
+        List<ProductTaxrateVo> list = productTaxrateService.queryList(bo);
+        ExcelUtil.exportExcel(list, "产品税率配置", ProductTaxrateVo.class, response);
+    }
+
+    /**
+     * 获取产品税率配置详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:taxrate:query")
+    @GetMapping("/{id}")
+    public R<ProductTaxrateVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(productTaxrateService.queryById(id));
+    }
+
+    /**
+     * 新增产品税率配置
+     */
+    @SaCheckPermission("system:taxrate:add")
+    @Log(title = "产品税率配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody ProductTaxrateBo bo) {
+        return toAjax(productTaxrateService.insertByBo(bo));
+    }
+
+    /**
+     * 修改产品税率配置
+     */
+    @SaCheckPermission("system:taxrate:edit")
+    @Log(title = "产品税率配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ProductTaxrateBo bo) {
+        return toAjax(productTaxrateService.updateByBo(bo));
+    }
+
+    /**
+     * 删除产品税率配置
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:taxrate:remove")
+    @Log(title = "产品税率配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(productTaxrateService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 1 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SupplierLevelController.java

@@ -50,7 +50,7 @@ public class SupplierLevelController extends BaseController {
     /**
      * 查询供应商等级列表
      */
-    @SaCheckPermission("system:level:list")
+    //@SaCheckPermission("system:level:list")
     @GetMapping("/list")
     public TableDataInfo<SupplierLevelVo> list(SupplierLevelBo bo, PageQuery pageQuery) {
         return supplierLevelService.queryPageList(bo, pageQuery);

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/SupplierTypeController.java

@@ -49,7 +49,7 @@ public class SupplierTypeController extends BaseController {
     /**
      * 查询供应商类别列表
      */
-    @SaCheckPermission("system:type:list")
+    //@SaCheckPermission("system:type:list")
     @GetMapping("/list")
     public TableDataInfo<SupplierTypeVo> list(SupplierTypeBo bo, PageQuery pageQuery) {
         return supplierTypeService.queryPageList(bo, pageQuery);
@@ -65,6 +65,7 @@ public class SupplierTypeController extends BaseController {
             RemoteSupplierTypeVo vo = new RemoteSupplierTypeVo();
             vo.setTypeId(item.getSupplierTypeNo());
             vo.setTypeName(item.getSupplierTypeName());
+            vo.setId(item.getId());
             vos.add(vo);
         });
         return R.ok(vos);

+ 67 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ProductTaxrate.java

@@ -0,0 +1,67 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 产品税率配置对象 product_taxrate
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("product_taxrate")
+public class ProductTaxrate extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键,自增ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 税率编号
+     */
+    private String taxrateNo;
+
+    /**
+     * 税率名称
+     */
+    private String taxrateName;
+
+    /**
+     * 税率
+     */
+    private Long taxrate;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 是否显示:1=是,0=否
+     */
+    private String isShow;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 54 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ProductTaxrateBo.java

@@ -0,0 +1,54 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.ProductTaxrate;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 产品税率配置业务对象 product_taxrate
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ProductTaxrate.class, reverseConvertGenerate = false)
+public class ProductTaxrateBo extends BaseEntity {
+
+    /**
+     * 主键,自增ID
+     */
+    private Long id;
+
+    /**
+     * 税率编号
+     */
+    private String taxrateNo;
+
+    /**
+     * 税率名称
+     */
+    private String taxrateName;
+
+    /**
+     * 税率
+     */
+    private Long taxrate;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 是否显示:1=是,0=否
+     */
+    private String isShow;
+
+
+}

+ 64 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProductTaxrateVo.java

@@ -0,0 +1,64 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.ProductTaxrate;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 产品税率配置视图对象 product_taxrate
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ProductTaxrate.class)
+public class ProductTaxrateVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    private Long id;
+
+    /**
+     * 税率编号
+     */
+    @ExcelProperty(value = "税率编号")
+    private String taxrateNo;
+
+    /**
+     * 税率名称
+     */
+    @ExcelProperty(value = "税率名称")
+    private String taxrateName;
+
+    /**
+     * 税率
+     */
+    @ExcelProperty(value = "税率")
+    private Long taxrate;
+
+    /**
+     * 数据来源
+     */
+    @ExcelProperty(value = "数据来源")
+    private String dataSource;
+
+    /**
+     * 是否显示:1=是,0=否
+     */
+    @ExcelProperty(value = "是否显示:1=是,0=否")
+    private String isShow;
+
+
+}

+ 2 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SupplierLevelVo.java

@@ -30,6 +30,8 @@ public class SupplierLevelVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
+    private Long id;
+
     /**
      * 编号
      */

+ 6 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/SupplierTypeVo.java

@@ -30,6 +30,12 @@ public class SupplierTypeVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
+
+    /**
+     * ID
+     */
+    private Long id;
+
     /**
      * 编号
      */

+ 15 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/ProductTaxrateMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.ProductTaxrate;
+import org.dromara.system.domain.vo.ProductTaxrateVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 产品税率配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface ProductTaxrateMapper extends BaseMapperPlus<ProductTaxrate, ProductTaxrateVo> {
+
+}

+ 70 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IProductTaxrateService.java

@@ -0,0 +1,70 @@
+package org.dromara.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.system.domain.ProductTaxrate;
+import org.dromara.system.domain.vo.ProductTaxrateVo;
+import org.dromara.system.domain.bo.ProductTaxrateBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 产品税率配置Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+public interface IProductTaxrateService extends IService<ProductTaxrate>{
+
+    /**
+     * 查询产品税率配置
+     *
+     * @param id 主键
+     * @return 产品税率配置
+     */
+    ProductTaxrateVo queryById(Long id);
+
+    /**
+     * 分页查询产品税率配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 产品税率配置分页列表
+     */
+    TableDataInfo<ProductTaxrateVo> queryPageList(ProductTaxrateBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的产品税率配置列表
+     *
+     * @param bo 查询条件
+     * @return 产品税率配置列表
+     */
+    List<ProductTaxrateVo> queryList(ProductTaxrateBo bo);
+
+    /**
+     * 新增产品税率配置
+     *
+     * @param bo 产品税率配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ProductTaxrateBo bo);
+
+    /**
+     * 修改产品税率配置
+     *
+     * @param bo 产品税率配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ProductTaxrateBo bo);
+
+    /**
+     * 校验并批量删除产品税率配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 133 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/ProductTaxrateServiceImpl.java

@@ -0,0 +1,133 @@
+package org.dromara.system.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 com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.system.domain.bo.ProductTaxrateBo;
+import org.dromara.system.domain.vo.ProductTaxrateVo;
+import org.dromara.system.domain.ProductTaxrate;
+import org.dromara.system.mapper.ProductTaxrateMapper;
+import org.dromara.system.service.IProductTaxrateService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 产品税率配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-19
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ProductTaxrateServiceImpl  extends ServiceImpl<ProductTaxrateMapper, ProductTaxrate> implements IProductTaxrateService {
+
+    private final ProductTaxrateMapper baseMapper;
+
+    /**
+     * 查询产品税率配置
+     *
+     * @param id 主键
+     * @return 产品税率配置
+     */
+    @Override
+    public ProductTaxrateVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询产品税率配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 产品税率配置分页列表
+     */
+    @Override
+    public TableDataInfo<ProductTaxrateVo> queryPageList(ProductTaxrateBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ProductTaxrate> lqw = buildQueryWrapper(bo);
+        Page<ProductTaxrateVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的产品税率配置列表
+     *
+     * @param bo 查询条件
+     * @return 产品税率配置列表
+     */
+    @Override
+    public List<ProductTaxrateVo> queryList(ProductTaxrateBo bo) {
+        LambdaQueryWrapper<ProductTaxrate> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ProductTaxrate> buildQueryWrapper(ProductTaxrateBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ProductTaxrate> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ProductTaxrate::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getDataSource()), ProductTaxrate::getDataSource, bo.getDataSource());
+        return lqw;
+    }
+
+    /**
+     * 新增产品税率配置
+     *
+     * @param bo 产品税率配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ProductTaxrateBo bo) {
+        ProductTaxrate add = MapstructUtils.convert(bo, ProductTaxrate.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改产品税率配置
+     *
+     * @param bo 产品税率配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ProductTaxrateBo bo) {
+        ProductTaxrate update = MapstructUtils.convert(bo, ProductTaxrate.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ProductTaxrate entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除产品税率配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/ProductTaxrateMapper.xml

@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<!DOCTYPE mapper
+PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
+"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
+<mapper namespace="org.dromara.system.mapper.ProductTaxrateMapper">
+
+</mapper>