Просмотр исходного кода

Merge remote-tracking branch 'origin/master' into master

肖路 2 месяцев назад
Родитель
Сommit
a0d479ff3c
76 измененных файлов с 4487 добавлено и 198 удалено
  1. 14 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteSupplierContractService.java
  2. 12 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteSupplierInfoService.java
  3. 30 0
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteContractProdcutService.java
  4. 8 0
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteProductService.java
  5. 72 0
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/domain/ContractProductDto.java
  6. 3 1
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteSupplierTypeVo.java
  7. 4 3
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  8. 16 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/ContractSupplyController.java
  9. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerInfoController.java
  10. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierAddressController.java
  11. 6 3
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierBankController.java
  12. 112 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierBusinessInfoController.java
  13. 0 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierContractController.java
  14. 7 2
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierProcurementController.java
  15. 9 7
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplyAreaController.java
  16. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/ContractSupply.java
  17. 109 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierBusinessInfo.java
  18. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierContract.java
  19. 80 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/ContractSupplyBo.java
  20. 91 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierBusinessInfoBo.java
  21. 85 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierContactBo.java
  22. 3 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierContractBo.java
  23. 1 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierInfoBo.java
  24. 8 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplyAreaBo.java
  25. 496 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyProductVo.java
  26. 9 3
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyVo.java
  27. 2 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerContactVo.java
  28. 112 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierBusinessInfoVo.java
  29. 14 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierContactVo.java
  30. 32 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierInfoVo.java
  31. 5 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplyAreaVo.java
  32. 25 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteSupplierContractServiceImpl.java
  33. 25 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteSupplierInfoServiceImpl.java
  34. 10 9
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/enums/SupplierStatusEnum.java
  35. 15 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/SupplierBusinessInfoMapper.java
  36. 2 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/IContractSupplyService.java
  37. 72 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierBusinessInfoService.java
  38. 7 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierContractService.java
  39. 2 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierInfoService.java
  40. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplyAreaService.java
  41. 119 6
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/ContractSupplyServiceImpl.java
  42. 9 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAddressServiceImpl.java
  43. 71 4
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAuthorizeServiceImpl.java
  44. 209 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierBusinessInfoServiceImpl.java
  45. 19 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContactServiceImpl.java
  46. 124 65
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContractServiceImpl.java
  47. 911 64
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java
  48. 5 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierProcurementServiceImpl.java
  49. 81 11
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplyAreaServiceImpl.java
  50. 7 0
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SupplierBusinessInfoMapper.xml
  51. 10 0
      ruoyi-modules/ruoyi-job/pom.xml
  52. 35 0
      ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/SupplierContractJobTask.java
  53. 32 0
      ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/SupplierInfoJobTask.java
  54. 23 0
      ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/TestTask.java
  55. 106 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ContractProductController.java
  56. 3 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBrandController.java
  57. 3 4
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductCategoryController.java
  58. 86 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ContractProduct.java
  59. 74 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ContractProductBo.java
  60. 94 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ContractProductVo.java
  61. 67 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteContractProductServiceImpl.java
  62. 16 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteProductServiceImpl.java
  63. 15 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ContractProductMapper.java
  64. 70 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IContractProductService.java
  65. 140 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ContractProductServiceImpl.java
  66. 7 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ContractProductMapper.xml
  67. 112 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/AddressAreaController.java
  68. 82 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/AddressArea.java
  69. 64 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/AddressAreaBo.java
  70. 85 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/AddressAreaVo.java
  71. 1 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSupplierTypeServiceImpl.java
  72. 15 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/mapper/AddressAreaMapper.java
  73. 72 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IAddressAreaService.java
  74. 209 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/AddressAreaServiceImpl.java
  75. 7 0
      ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/AddressAreaMapper.xml
  76. 1 1
      ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties

+ 14 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteSupplierContractService.java

@@ -0,0 +1,14 @@
+package org.dromara.customer.api;
+
+/**
+ * author
+ * 时间:2026/1/23,9:21
+ */
+public interface RemoteSupplierContractService {
+
+    /**
+     * 获取待审核 以及 生效的合同,并通过定时任务批量更新合同状态
+     */
+    int updateExpiredContractStatus();
+
+}

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

@@ -0,0 +1,12 @@
+package org.dromara.customer.api;
+
+/**
+ * author
+ * 时间:2026/1/23,9:43
+ */
+public interface RemoteSupplierInfoService {
+    /**
+     * 通过生效状态下判断有效期来更新是否停用
+     */
+    int updateIsDisable();
+}

+ 30 - 0
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteContractProdcutService.java

@@ -0,0 +1,30 @@
+package org.dromara.product.api;
+
+/**
+ * author
+ * 时间:2026/1/20,13:52
+ */
+
+import org.dromara.common.core.domain.R;
+import org.dromara.product.api.domain.ContractProductDto;
+import org.springframework.web.bind.annotation.RequestBody;
+
+import java.util.List;
+
+/**
+ * 产品与协议供货合同表示接口
+ */
+public interface RemoteContractProdcutService {
+
+    /**
+     * 批量添加商品合同信息
+     * @param bo
+     * @return
+     */
+    boolean add(List<ContractProductDto> bo) ;
+
+    List<ContractProductDto> queryList(Long contractSupplyId);
+
+    boolean delete(Long contractSupplyId);
+
+}

+ 8 - 0
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteProductService.java

@@ -47,6 +47,14 @@ public interface RemoteProductService {
     * */
     RemoteProductBrand getProductByBrandId(Long brandId);
 
+
+    /**
+     * 根据品牌id集合获取品牌名称
+     * @param ids
+     * @return
+     */
+    List<RemoteProductBrand> getProductByBrandId(List<Long> ids);
+
     /**
      * 获取品目列表
      */

+ 72 - 0
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/domain/ContractProductDto.java

@@ -0,0 +1,72 @@
+package org.dromara.product.api.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * author
+ * 时间:2026/1/20,13:50
+ */
+@Data
+public class ContractProductDto implements Serializable {
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 合同供货编号
+     */
+    private String contractSupplyNo;
+
+    /**
+     * 合同供货Id
+     */
+    private Long contractSupplyId;
+
+    /**
+     * 产品编号
+     */
+    private String productNo;
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 供货周期(单位:天/月,根据业务定义)
+     */
+    private Long supplyCycle;
+
+    /**
+     * 库存属性
+     */
+    private String inventoryProperties;
+
+    /**
+     * 最小供货量
+     */
+    private Long minSupply;
+
+    /**
+     * 报价(支持大文本)
+     */
+    private String offerPrice;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+}

+ 3 - 1
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteSupplierTypeVo.java

@@ -2,12 +2,14 @@ package org.dromara.system.api.domain.vo;
 
 import lombok.Data;
 
+import java.io.Serializable;
+
 /**
  * author
  * 时间:2026/1/13,16:10
  */
 @Data
-public class RemoteSupplierTypeVo {
+public class RemoteSupplierTypeVo implements Serializable {
     private long id;
 
     private String typeId;

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

@@ -78,10 +78,11 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "com_",
         "product_",
         "supplier_level",
-        "industry_category",
         "enterprise_scale",
-        "supplier_contact"
-
+        "industry_category",
+        "contract_product",
+        "supplier_contact",
+        "address_area"
 
 
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法

+ 16 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/ContractSupplyController.java

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -67,6 +68,7 @@ public class ContractSupplyController extends BaseController {
     @GetMapping("/{id}")
     public R<ContractSupplyVo> getInfo(@NotNull(message = "主键不能为空")
                                      @PathVariable("id") Long id) {
+
         return R.ok(contractSupplyService.queryById(id));
     }
 
@@ -77,6 +79,7 @@ public class ContractSupplyController extends BaseController {
     @Log(title = "协议供货", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
+    @Transactional
     public R<Void> add(@Validated(AddGroup.class) @RequestBody ContractSupplyBo bo) {
         return toAjax(contractSupplyService.insertByBo(bo));
     }
@@ -92,6 +95,19 @@ public class ContractSupplyController extends BaseController {
         return toAjax(contractSupplyService.updateByBo(bo));
     }
 
+    /**
+     * 审核
+     * @param bo
+     * @return
+     */
+    @PutMapping("/edit")
+    public R<Void> approve(@RequestBody ContractSupplyBo bo) {
+        return toAjax(contractSupplyService.aprprove(bo));
+    }
+
+
+
+
     /**
      * 删除协议供货
      *

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

@@ -118,7 +118,7 @@ public class CustomerInfoController extends BaseController {
     @Log(title = "客户信息", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
-    public R<Void> edit(@Validated(EditGroup.class) @RequestBody CustomerInfoBo bo) {
+    public R<Void> edit(@RequestBody CustomerInfoBo bo) {
         return toAjax(customerInfoService.updateByBo(bo));
     }
 

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

@@ -104,7 +104,7 @@ public class SupplierAddressController extends BaseController {
      *
      * @param ids 主键串
      */
-    @SaCheckPermission("supplierAddress:supplieraddress:remove")
+    //@SaCheckPermission("supplierAddress:supplieraddress:remove")
     @Log(title = "供应商地址", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空")

+ 6 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierBankController.java

@@ -2,6 +2,7 @@ package org.dromara.customer.controller;
 
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
@@ -71,9 +72,11 @@ public class SupplierBankController extends BaseController {
 
     @SaCheckPermission("customer:bank:query")
     @GetMapping("/getBankBySupplierId")
-    public R<SupplierBankVo> getBankBySupplierId(@RequestParam Long id) {
-        SupplierBankVo supplierBankVo =supplierBankService.selectBySupplierId(id);
-        return R.ok(supplierBankVo);
+    public R<List<SupplierBankVo>> getBankBySupplierId(@RequestParam Long id) {
+        SupplierBankBo supplierBankBo = new SupplierBankBo();
+        supplierBankBo.setSupplierId(id);
+        List<SupplierBankVo> supplierBankVos = supplierBankService.queryList(supplierBankBo);
+        return R.ok(supplierBankVos);
     }
 
 

+ 112 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierBusinessInfoController.java

@@ -0,0 +1,112 @@
+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.SupplierBusinessInfoVo;
+import org.dromara.customer.domain.bo.SupplierBusinessInfoBo;
+import org.dromara.customer.service.ISupplierBusinessInfoService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 供应商工商注册信息
+ * 前端访问路由地址为:/suuplier/businessInfo
+ *
+ * @author LionLi
+ * @date 2026-01-22
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/sbusinessInfo")
+public class SupplierBusinessInfoController extends BaseController {
+
+    private final ISupplierBusinessInfoService supplierBusinessInfoService;
+
+    /**
+     * 查询供应商工商注册信息列表
+     */
+    @SaCheckPermission("suuplier:businessInfo:list")
+    @GetMapping("/list")
+    public TableDataInfo<SupplierBusinessInfoVo> list(SupplierBusinessInfoBo bo, PageQuery pageQuery) {
+        return supplierBusinessInfoService.queryPageList(bo, pageQuery);
+    }
+
+    @GetMapping("/getinformation")
+    public R<SupplierBusinessInfoVo> getinformation(@RequestParam("enterpriseName") String enterpriseName)
+    {
+        return R.ok(supplierBusinessInfoService.getinformation(enterpriseName));
+    }
+
+    /**
+     * 导出供应商工商注册信息列表
+     */
+    @SaCheckPermission("suuplier:businessInfo:export")
+    @Log(title = "供应商工商注册信息", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(SupplierBusinessInfoBo bo, HttpServletResponse response) {
+        List<SupplierBusinessInfoVo> list = supplierBusinessInfoService.queryList(bo);
+        ExcelUtil.exportExcel(list, "供应商工商注册信息", SupplierBusinessInfoVo.class, response);
+    }
+
+    /**
+     * 获取供应商工商注册信息详细信息
+     *
+     * @param supplierId 主键
+     */
+    @SaCheckPermission("suuplier:businessInfo:query")
+    @GetMapping("/{supplierId}")
+    public R<SupplierBusinessInfoVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("supplierId") Long supplierId) {
+        return R.ok(supplierBusinessInfoService.queryById(supplierId));
+    }
+
+    /**
+     * 新增供应商工商注册信息
+     */
+    @SaCheckPermission("suuplier:businessInfo:add")
+    @Log(title = "供应商工商注册信息", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody SupplierBusinessInfoBo bo) {
+        return toAjax(supplierBusinessInfoService.insertByBo(bo));
+    }
+
+    /**
+     * 修改供应商工商注册信息
+     */
+    @SaCheckPermission("suuplier:businessInfo:edit")
+    @Log(title = "供应商工商注册信息", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody SupplierBusinessInfoBo bo) {
+        return toAjax(supplierBusinessInfoService.updateByBo(bo));
+    }
+
+    /**
+     * 删除供应商工商注册信息
+     *
+     * @param supplierIds 主键串
+     */
+    @SaCheckPermission("suuplier:businessInfo:remove")
+    @Log(title = "供应商工商注册信息", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{supplierIds}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("supplierIds") Long[] supplierIds) {
+        return toAjax(supplierBusinessInfoService.deleteWithValidByIds(List.of(supplierIds), true));
+    }
+}

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

@@ -57,8 +57,6 @@ public class SupplierContractController extends BaseController {
 
     }
 
-
-
     /**
      * 导出合同管理列表
      */

+ 7 - 2
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplierProcurementController.java

@@ -2,10 +2,12 @@ package org.dromara.customer.controller;
 
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.customer.domain.SupplierProcurement;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -72,18 +74,21 @@ public class SupplierProcurementController extends BaseController {
     /**
      * 新增供应商采购结算配置
      */
-    @SaCheckPermission("supplier:procurement:add")
     @Log(title = "供应商采购结算配置", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
     public R<Void> add(@Validated(AddGroup.class) @RequestBody SupplierProcurementBo bo) {
+        SupplierProcurement one = supplierProcurementService.getOne(new LambdaQueryWrapper<SupplierProcurement>()
+            .eq(SupplierProcurement::getSupplierId, bo.getSupplierId()));
+        if (one != null){
+            return toAjax(supplierProcurementService.updateByBo(bo));
+        }
         return toAjax(supplierProcurementService.insertByBo(bo));
     }
 
     /**
      * 修改供应商采购结算配置
      */
-    @SaCheckPermission("supplier:procurement:edit")
     @Log(title = "供应商采购结算配置", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()

+ 9 - 7
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/SupplyAreaController.java

@@ -6,6 +6,7 @@ import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.web.bind.annotation.*;
 import org.springframework.validation.annotation.Validated;
 import org.dromara.common.idempotent.annotation.RepeatSubmit;
@@ -40,7 +41,7 @@ public class SupplyAreaController extends BaseController {
     /**
      * 查询供应区域列表
      */
-    @SaCheckPermission("supplier:area:list")
+    //@SaCheckPermission("supplier:area:list")
     @GetMapping("/list")
     public TableDataInfo<SupplyAreaVo> list(SupplyAreaBo bo, PageQuery pageQuery) {
         return supplyAreaService.queryPageList(bo, pageQuery);
@@ -52,7 +53,7 @@ public class SupplyAreaController extends BaseController {
     /**
      * 导出供应区域列表
      */
-    @SaCheckPermission("supplier:area:export")
+    //@SaCheckPermission("supplier:area:export")
     @Log(title = "供应区域", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     public void export(SupplyAreaBo bo, HttpServletResponse response) {
@@ -65,9 +66,9 @@ public class SupplyAreaController extends BaseController {
      *
      * @param id 主键
      */
-    @SaCheckPermission("supplier:area:query")
+    //@SaCheckPermission("supplier:area:query")
     @GetMapping("/{id}")
-    public R<SupplyAreaVo> getInfo(@NotNull(message = "主键不能为空")
+    public R<List<SupplyAreaVo>> getInfo(@NotNull(message = "主键不能为空")
                                      @PathVariable("id") Long id) {
         return R.ok(supplyAreaService.queryById(id));
     }
@@ -75,10 +76,11 @@ public class SupplyAreaController extends BaseController {
     /**
      * 新增供应区域
      */
-    @SaCheckPermission("supplier:area:add")
+    //@SaCheckPermission("supplier:area:add")
     @Log(title = "供应区域", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
+    @Transactional
     public R<Void> add(@Validated(AddGroup.class) @RequestBody SupplyAreaBo bo) {
         return toAjax(supplyAreaService.insertByBo(bo));
     }
@@ -86,7 +88,7 @@ public class SupplyAreaController extends BaseController {
     /**
      * 修改供应区域
      */
-    @SaCheckPermission("supplier:area:edit")
+    //@SaCheckPermission("supplier:area:edit")
     @Log(title = "供应区域", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
@@ -99,7 +101,7 @@ public class SupplyAreaController extends BaseController {
      *
      * @param ids 主键串
      */
-    @SaCheckPermission("supplier:area:remove")
+    //@SaCheckPermission("supplier:area:remove")
     @Log(title = "供应区域", businessType = BusinessType.DELETE)
     @DeleteMapping("/{ids}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空")

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/ContractSupply.java

@@ -32,7 +32,7 @@ public class ContractSupply extends TenantEntity {
     /**
      * 协议单号
      */
-    private Long contractSupplyNo;
+    private String contractSupplyNo;
 
     /**
      * 供应商编号

+ 109 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/SupplierBusinessInfo.java

@@ -0,0 +1,109 @@
+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.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+import java.io.Serial;
+
+/**
+ * 供应商工商注册信息对象 supplier_business_info
+ *
+ * @author LionLi
+ * @date 2026-01-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("supplier_business_info")
+public class SupplierBusinessInfo extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 关联供应商ID
+     */
+    @TableId(value = "supplier_id")
+    private Long supplierId;
+
+    /**
+     * 工商全称
+     */
+    private String businessName;
+
+    /**
+     * 统一社会信用代码
+     */
+    private String socialCreditCode;
+
+    /**
+     * 法人姓名
+     */
+    private String legalPersonName;
+
+    /**
+     * 注册资本
+     */
+    private String registeredCapital;
+
+    /**
+     * 实缴资本
+     */
+    private String paidInCapital;
+
+    /**
+     * 成立日期
+     */
+    private Date establishmentDate;
+
+    /**
+     * 吊销日期
+     */
+    private Date revocationDate;
+
+    /**
+     * 登记状态
+     */
+    private String registrationStatus;
+
+    /**
+     * 登记机关
+     */
+    private String registrationAuthority;
+
+    /**
+     * 经营范围
+     */
+    private String bussinessRange;
+
+    /**
+     * 营业执照路径
+     */
+    private String businessLicense;
+
+    /**
+     * 工商地址-详细地址
+     */
+    private String businessAddress;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

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

@@ -84,7 +84,7 @@ public class SupplierContract extends TenantEntity {
     /**
      * 税率(如13%/9%/6%)
      */
-    private BigDecimal taxRate;
+    private Long taxRate;
 
     /**
      * 结算方式(如月结/季结/一次性)

+ 80 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/ContractSupplyBo.java

@@ -1,5 +1,7 @@
 package org.dromara.customer.domain.bo;
 
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
 import org.dromara.customer.domain.ContractSupply;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.core.validate.AddGroup;
@@ -9,7 +11,10 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
 import java.util.Date;
+import java.util.List;
+
 import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.product.api.domain.ContractProductDto;
 
 /**
  * 协议供货业务对象 contract_supply
@@ -22,10 +27,35 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 @AutoMapper(target = ContractSupply.class, reverseConvertGenerate = false)
 public class ContractSupplyBo extends BaseEntity {
 
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
     /**
      * 协议单号
      */
-    private Long contractSupplyNo;
+    private String contractSupplyNo;
+
+    /**
+     * 供应商编号
+     */
+    private String supplyNo;
+    /**
+     * 供应商名称
+     */
+    private String supplierName;
+
+    /**
+     * 供应商ID
+     */
+    private Long supplierId;
+
+    /**
+     * 商品数量
+     */
+    private Long productNumber;
 
     /**
      * 开始时间
@@ -37,5 +67,54 @@ public class ContractSupplyBo extends BaseEntity {
      */
     private Date endTime;
 
+    /**
+     * 审核时间
+     */
+    private Date auditTime;
+
+    /**
+     * 价格周期(单位:天/月,根据业务定义)
+     */
+    private Long priceCycle;
+
+    /**
+     * 配送方式(如:自提、快递、送货上门等)
+     */
+    private String deliveryMethod;
+
+    /**
+     * 结算方式(如:月结、现结、账期等)
+     */
+    private String settlementMethod;
+
+    /**
+     * 价格说明(详细描述定价规则、优惠政策等)
+     */
+    private String priceDescription;
+
+    /**
+     * 附件文件路径
+     */
+    private String proFile;
+
+    /**
+     * 附件文件名
+     */
+    private String proFileName;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+
+    /**
+     * 备注信息
+     */
+    private String remark;
+
+
+    private List<ContractProductDto> contractProduct;
+
 
 }

+ 91 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierBusinessInfoBo.java

@@ -0,0 +1,91 @@
+package org.dromara.customer.domain.bo;
+
+import org.dromara.customer.domain.SupplierBusinessInfo;
+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.*;
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+
+/**
+ * 供应商工商注册信息业务对象 supplier_business_info
+ *
+ * @author LionLi
+ * @date 2026-01-22
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = SupplierBusinessInfo.class, reverseConvertGenerate = false)
+public class SupplierBusinessInfoBo extends BaseEntity {
+
+    /**
+     * 关联供应商ID
+     */
+    private Long supplierId;
+
+    /**
+     * 工商全称
+     */
+    private String businessName;
+
+    /**
+     * 统一社会信用代码
+     */
+    private String socialCreditCode;
+
+    /**
+     * 法人姓名
+     */
+    private String legalPersonName;
+
+    /**
+     * 注册资本
+     */
+    private String registeredCapital;
+
+    /**
+     * 实缴资本
+     */
+    private String paidInCapital;
+
+    /**
+     * 成立日期
+     */
+    private Date establishmentDate;
+
+    /**
+     * 吊销日期
+     */
+    private Date revocationDate;
+
+    /**
+     * 登记状态
+     */
+    private String registrationStatus;
+
+    /**
+     * 登记机关
+     */
+    private String registrationAuthority;
+
+    /**
+     * 经营范围
+     */
+    private String bussinessRange;
+
+    /**
+     * 营业执照路径
+     */
+    private String businessLicense;
+
+    /**
+     * 工商地址-详细地址
+     */
+    private String businessAddress;
+
+
+}

+ 85 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierContactBo.java

@@ -1,5 +1,7 @@
 package org.dromara.customer.domain.bo;
 
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableLogic;
 import org.dromara.customer.domain.SupplierContact;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.core.validate.AddGroup;
@@ -20,18 +22,25 @@ import jakarta.validation.constraints.*;
 @AutoMapper(target = SupplierContact.class, reverseConvertGenerate = false)
 public class SupplierContactBo extends BaseEntity {
 
+    private Long id;
+
     /**
      * 供应商编号
      */
     private String supplierNo;
 
+    /**
+     * 供应商名称
+     */
+    private String supplierName;
+
     /**
      * 供应商ID
      */
     private Long supplierId;
 
     /**
-     * 员工编号
+     * 用户ID
      */
     private String userNo;
 
@@ -45,10 +54,85 @@ public class SupplierContactBo extends BaseEntity {
      */
     private String phone;
 
+    /**
+     * 联系地址
+     */
+    private String connAddr;
+
+    /**
+     * 员工密码
+     */
+    private String password;
+
+    /**
+     * 角色
+     */
+    private String roleNo;
+
+    /**
+     * 部门
+     */
+    private String departmentNo;
+
+    /**
+     * 职位
+     */
+    private String position;
+
+    /**
+     * 联系人描述
+     */
+    private String userDescribe;
+
+    /**
+     * 主要联系人
+     */
+    private String isPrimaryContact;
+
+    /**
+     * 允许登录供应商端
+     */
+    private String isRegister;
+
+    /**
+     * 办公电话
+     */
+    private String officePhone;
+
+    /**
+     * 性别(0未知 1男 2女)
+     */
+    private String gender;
+
+    /**
+     * 对接人编号
+     */
+    private Long abutmentNo;
+
+    /**
+     * 数据推送状态(0未推送 1已推送 2推送失败)
+     */
+    private String pushStatus;
+
+    /**
+     * 行标识(预留字段)
+     */
+    private String rowCd;
+
     /**
      * 状态(0正常 1停用)
      */
     private String status;
 
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注信息
+     */
+    private String remark;
+
 
 }

+ 3 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierContractBo.java

@@ -24,6 +24,8 @@ import com.fasterxml.jackson.annotation.JsonFormat;
 @AutoMapper(target = SupplierContract.class, reverseConvertGenerate = false)
 public class SupplierContractBo extends BaseEntity {
 
+    private Long id;
+
     /**
      * 供应商编号
      */
@@ -77,7 +79,7 @@ public class SupplierContractBo extends BaseEntity {
     /**
      * 税率(如13%/9%/6%)
      */
-    private BigDecimal taxRate;
+    private Long taxRate;
 
     /**
      * 合同金额

+ 1 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplierInfoBo.java

@@ -59,6 +59,7 @@ public class SupplierInfoBo extends BaseEntity {
     //@NotBlank(message = "合作类型不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long cooperationType;
 
+
     /**
      * 固定电话
      */

+ 8 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SupplyAreaBo.java

@@ -1,5 +1,6 @@
 package org.dromara.customer.domain.bo;
 
+import org.dromara.common.core.validate.enumd.EnumPattern;
 import org.dromara.customer.domain.SupplyArea;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.core.validate.AddGroup;
@@ -9,6 +10,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
 
+import java.util.List;
+
 /**
  * 供应区域业务对象 supply_area
  *
@@ -20,6 +23,8 @@ import jakarta.validation.constraints.*;
 @AutoMapper(target = SupplyArea.class, reverseConvertGenerate = false)
 public class SupplyAreaBo extends BaseEntity {
 
+    private Long id;
+
     /**
      * 供应商编号(关联供应商主表)
      */
@@ -51,4 +56,7 @@ public class SupplyAreaBo extends BaseEntity {
     private String level;
 
 
+    private List<SupplyAreaBo> areaList;
+
+
 }

+ 496 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyProductVo.java

@@ -0,0 +1,496 @@
+package org.dromara.customer.domain.vo;
+
+import cn.idev.excel.annotation.ExcelProperty;
+import lombok.Data;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+
+import java.math.BigDecimal;
+
+/**
+ * author
+ * 时间:2026/1/20,15:46
+ */
+@Data
+public class ContractSupplyProductVo {
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 合同供货编号
+     */
+    private String contractSupplyNo;
+
+    /**
+     * 合同供货Id
+     */
+    private Long contractSupplyId;
+
+    /**
+     * 产品编号
+     */
+    private String productNo;
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 供货周期(单位:天/月,根据业务定义)
+     */
+    private Long supplyCycle;
+
+    /**
+     * 库存属性
+     */
+    private String inventoryProperties;
+
+    /**
+     * 最小供货量
+     */
+    private Long minSupply;
+
+    /**
+     * 报价(支持大文本)
+     */
+    private String offerPrice;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+
+
+
+    /**
+     * 产品名称
+     */
+    @ExcelProperty(value = "项目名称")
+    private String itemName;
+
+    /**
+     * 品牌id
+     */
+    @ExcelProperty(value = "品牌id")
+    private Long brandId;
+
+    /**
+     * 品牌名称
+     */
+    private String brandName;
+
+    /**
+     * 顶级分类id
+     */
+    @ExcelProperty(value = "顶级分类id")
+    private Long topCategoryId;
+
+    /**
+     * 中级分类id
+     */
+    @ExcelProperty(value = "中级分类id")
+    private Long mediumCategoryId;
+
+    /**
+     * 底层分类id
+     */
+    @ExcelProperty(value = "底层分类id")
+    private Long bottomCategoryId;
+
+    /**
+     * 分类名称(底级分类)
+     */
+    private String categoryName;
+
+    /**
+     * 顶级分类名称
+     */
+    private String topCategoryName;
+
+    /**
+     * 中级分类名称
+     */
+    private String mediumCategoryName;
+
+    /**
+     * 底级分类名称
+     */
+    private String bottomCategoryName;
+
+    /**
+     * 单位id
+     */
+    @ExcelProperty(value = "单位id")
+    private String unitId;
+
+    /**
+     * 单位名称(如:件、箱、千克等)
+     */
+    private String unitName;
+
+    /**
+     * 产品图片URL
+     */
+    @ExcelProperty(value = "产品图片URL")
+    private String productImage;
+
+    /**
+     * 是否自营(1=是,0=否)
+     */
+    @ExcelProperty(value = "是否自营", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "1==是,0=否")
+    private Integer isSelf;
+
+    /**
+     * 商品类型 1=默认类型,2精选商品,3=停售商品
+     * */
+    private Integer productCategory;
+
+    /**
+     * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+    @ExcelProperty(value = "产品审核状态 0=待采购审核,1=审核通过,2=驳回,3=待营销审核")
+    private Integer productReviewStatus;
+
+    /**
+     * 审核意见
+     * */
+    @ExcelProperty(value = "审核意见")
+    private String reviewComments;
+
+    /**
+     * 首页推荐:1=推荐,0=不推荐
+     */
+    @ExcelProperty(value = "首页推荐:1=推荐,0=不推荐")
+    private Integer homeRecommended;
+
+    /**
+     * 分类推荐:1=推荐,0=不推荐
+     */
+    @ExcelProperty(value = "分类推荐:1=推荐,0=不推荐")
+    private Integer categoryRecommendation;
+
+    /**
+     * 购物车推荐:1=推荐,0=不推荐
+     */
+    @ExcelProperty(value = "购物车推荐:1=推荐,0=不推荐")
+    private Integer cartRecommendation;
+
+    /**
+     * 推荐产品顺序
+     */
+    @ExcelProperty(value = "推荐产品顺序")
+    private Long recommendedProductOrder;
+
+    /**
+     * 是否热门:1=是,0=否
+     */
+    @ExcelProperty(value = "是否热门:1=是,0=否")
+    private Integer isPopular;
+
+    /**
+     * 是否新品:1=是,0=否
+     */
+    @ExcelProperty(value = "是否新品:1=是,0=否")
+    private Integer isNew;
+
+    /**
+     * 商品状态:1=已上架,0=下架 2 上架中等
+     */
+    @ExcelProperty(value = "商品状态:1=已上架,0=下架 2 上架中等")
+    private Integer productStatus;
+
+    /**
+     * 数据来源
+     */
+    @ExcelProperty(value = "数据来源")
+    private String dataSource;
+
+    /**
+     * 市场价
+     * */
+    @ExcelProperty(value = "市场价")
+    private BigDecimal marketPrice;
+
+    /**
+     * 会员价格
+     */
+    @ExcelProperty(value = "会员价格")
+    private BigDecimal memberPrice;
+
+    /**
+     * 最低销售价格
+     */
+    @ExcelProperty(value = "最低销售价格")
+    private BigDecimal minSellingPrice;
+
+    /**
+     * 采购价格
+     */
+    @ExcelProperty(value = "采购价格")
+    private BigDecimal purchasingPrice;
+
+
+    /**
+     * 暂估毛利率
+     * */
+    @ExcelProperty(value = "暂估毛利率")
+    private BigDecimal tempGrossMargin;
+
+
+    /**
+     * A10产品名称
+     */
+    @ExcelProperty(value = "A10产品名称")
+    private String a10ProductName;
+
+    /**
+     * 规格型号
+     */
+    @ExcelProperty(value = "规格型号")
+    private String specification;
+
+    /**
+     * UPC(S)条码
+     */
+    @ExcelProperty(value = "UPC(S)条码")
+    private String upcBarcode;
+
+    /**
+     * 发票名称
+     */
+    @ExcelProperty(value = "发票名称")
+    private String invoiceName;
+
+    /**
+     * 发票规格
+     */
+    @ExcelProperty(value = "发票规格")
+    private String invoiceSpec;
+
+    /**
+     * 包装规格
+     */
+    @ExcelProperty(value = "包装规格")
+    private String packagingSpec;
+
+    /**
+     * 参考链接
+     */
+    @ExcelProperty(value = "参考链接")
+    private String referenceLink;
+
+    /**
+     * 商品重量
+     */
+    @ExcelProperty(value = "商品重量")
+    private String weight;
+
+    /**
+     * 重量单位
+     */
+    @ExcelProperty(value = "重量单位")
+    private String weightUnit;
+
+    /**
+     * 商品体积
+     */
+    @ExcelProperty(value = "商品体积")
+    private String volume;
+
+    /**
+     * 体积单位
+     */
+    @ExcelProperty(value = "体积单位")
+    private String volumeUnit;
+
+    /**
+     * 主库简介
+     */
+    @ExcelProperty(value = "主库简介")
+    private String mainLibraryIntro;
+
+    /**
+     * 售后服务
+     */
+    @ExcelProperty(value = "售后服务")
+    private String afterSalesService;
+
+    /**
+     * 服务保证 - 无忧退货
+     */
+    @ExcelProperty(value = "无忧退货")
+    private String worryFreeReturn;
+
+    /**
+     * 服务保证 - 快速退款
+     */
+    @ExcelProperty(value = "快速退款")
+    private String quickRefund;
+
+    /**
+     * 服务保证 - 免费包邮
+     */
+    @ExcelProperty(value = "免费包邮")
+    private String freeShipping;
+
+    /**
+     * 服务保证 - 正品保障
+     */
+    @ExcelProperty(value = "正品保障")
+    private String genuineGuarantee;
+
+    /**
+     * 安装服务 - 免费安装
+     */
+    @ExcelProperty(value = "免费安装")
+    private String freeInstallation;
+
+    /**
+     * 中档价
+     */
+    @ExcelProperty(value = "中档价")
+    private BigDecimal midRangePrice;
+
+    /**
+     * 平档价
+     */
+    @ExcelProperty(value = "平档价")
+    private BigDecimal standardPrice;
+
+    /**
+     * 套证价
+     */
+    @ExcelProperty(value = "套证价")
+    private BigDecimal certificatePrice;
+
+    /**
+     * 采购价
+     */
+    @ExcelProperty(value = "采购价")
+    private BigDecimal purchasePrice;
+
+    /**
+     * 暂估采购价
+     */
+    @ExcelProperty(value = "暂估采购价")
+    private BigDecimal estimatedPurchasePrice;
+
+    /**
+     * 产品性质
+     */
+    @ExcelProperty(value = "产品性质")
+    private String productNature;
+
+    /**
+     * 采购人员
+     */
+    @ExcelProperty(value = "采购人员")
+    private String purchasingPersonnel;
+
+    /**
+     * 商品详情 - 电脑端
+     */
+    @ExcelProperty(value = "电脑端详情")
+    private String pcDetail;
+
+    /**
+     * 商品详情 - 移动端
+     */
+    @ExcelProperty(value = "移动端详情")
+    private String mobileDetail;
+
+    /**
+     * 税率
+     */
+    @ExcelProperty(value = "税率")
+    private BigDecimal taxRate;
+
+    /**
+     * 币种
+     */
+    @ExcelProperty(value = "币种")
+    private String currency;
+
+    /**
+     * 最低起订量
+     */
+    @ExcelProperty(value = "最低起订量")
+    private Long minOrderQuantity;
+
+    /**
+     * 总库存
+     * */
+    private Long totalInventory;
+    /**
+     * 当前可用库存
+     * */
+    private Long nowInventory;
+
+    /**
+     * 虚拟库存
+     * */
+    private Long virtualInventory;
+
+    /**
+     * 是否可定制
+     */
+    private Boolean customizable;
+
+    /**
+     * 定制说明
+     */
+    private String customDescription;
+
+    /**
+     * 定制详情列表(JSON字符串)
+     */
+    private String customDetailsJson;
+
+    /**
+     * 服务保障(逗号分隔的ID列表)
+     */
+    private String serviceGuarantee;
+
+    /**
+     * 商品属性值(JSON字符串)
+     */
+    private String attributesList;
+
+    /**
+     * 销售量/销量人气
+     */
+    private Long salesVolume;
+
+    /**
+     * 定制方式(逗号分隔)
+     */
+    private String customizedStyle;
+
+    /**
+     * 定制工艺(逗号分隔)
+     */
+    private String customizedCraft;
+
+    /**
+     * 推送状态 0未推送,1已推送
+     */
+    private Long pushStatus;
+
+
+}

+ 9 - 3
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/ContractSupplyVo.java

@@ -11,11 +11,12 @@ import org.dromara.common.excel.annotation.ExcelDictFormat;
 import org.dromara.common.excel.convert.ExcelDictConvert;
 import io.github.linpeilie.annotations.AutoMapper;
 import lombok.Data;
+import org.dromara.product.api.domain.ContractProductDto;
 
 import java.io.Serial;
 import java.io.Serializable;
 import java.util.Date;
-
+import java.util.List;
 
 
 /**
@@ -32,11 +33,13 @@ public class ContractSupplyVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
+
+    private Long id;
     /**
      * 协议单号
      */
     @ExcelProperty(value = "协议单号")
-    private Long contractSupplyNo;
+    private String contractSupplyNo;
 
     /**
      * 供应商编号
@@ -73,16 +76,19 @@ public class ContractSupplyVo implements Serializable {
     private Date endTime;
 
     /**
-     * 状态(0正常 1停用
+     * 状态(0未生效 1生效
      */
     @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
     @ExcelDictFormat(dictType = "contract_supplier_status")
     private String status;
 
+    private String remark;
     /**
      * 剩余时限(天)
      */
     private String timeRemaining;
 
+    private List<ContractSupplyProductVo> contractProduct;
+
 
 }

+ 2 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerContactVo.java

@@ -39,6 +39,8 @@ public class CustomerContactVo implements Serializable {
     @ExcelProperty(value = "所属客户ID")
     private Long customerId;
 
+
+
     /**
      * 联系人姓名
      */

+ 112 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierBusinessInfoVo.java

@@ -0,0 +1,112 @@
+package org.dromara.customer.domain.vo;
+
+import java.util.Date;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import org.dromara.customer.domain.SupplierBusinessInfo;
+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_business_info
+ *
+ * @author LionLi
+ * @date 2026-01-22
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = SupplierBusinessInfo.class)
+public class SupplierBusinessInfoVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 关联客户ID
+     */
+    @ExcelProperty(value = "关联供应商ID")
+    private Long supplierId;
+
+    /**
+     * 工商全称
+     */
+    @ExcelProperty(value = "工商全称")
+    private String businessName;
+
+    /**
+     * 统一社会信用代码
+     */
+    @ExcelProperty(value = "统一社会信用代码")
+    private String socialCreditCode;
+
+    /**
+     * 法人姓名
+     */
+    @ExcelProperty(value = "法人姓名")
+    private String legalPersonName;
+
+    /**
+     * 注册资本
+     */
+    @ExcelProperty(value = "注册资本")
+    private String registeredCapital;
+
+    /**
+     * 实缴资本
+     */
+    @ExcelProperty(value = "实缴资本")
+    private String paidInCapital;
+
+    /**
+     * 成立日期
+     */
+    @ExcelProperty(value = "成立日期")
+    private Date establishmentDate;
+
+    /**
+     * 吊销日期
+     */
+    @ExcelProperty(value = "吊销日期")
+    private Date revocationDate;
+
+    /**
+     * 登记状态
+     */
+    @ExcelProperty(value = "登记状态")
+    private String registrationStatus;
+
+    /**
+     * 登记机关
+     */
+    @ExcelProperty(value = "登记机关")
+    private String registrationAuthority;
+
+    /**
+     * 经营范围
+     */
+    @ExcelProperty(value = "经营范围")
+    private String bussinessRange;
+
+    /**
+     * 营业执照路径
+     */
+    @ExcelProperty(value = "营业执照路径")
+    private String businessLicense;
+
+    /**
+     * 工商地址-详细地址
+     */
+    @ExcelProperty(value = "工商地址-详细地址")
+    private String businessAddress;
+
+
+}

+ 14 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierContactVo.java

@@ -28,6 +28,7 @@ public class SupplierContactVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
+    private Long id;
     /**
      * 供应商编号
      */
@@ -112,4 +113,17 @@ public class SupplierContactVo implements Serializable {
     private String status;
 
 
+    private String officePhone;
+
+    /**
+     * 联系地址
+     */
+    private String connAddr;
+
+    /**
+     * 用户描述
+     */
+    private String userDescribe;
+
+
 }

+ 32 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplierInfoVo.java

@@ -261,7 +261,7 @@ public class SupplierInfoVo implements Serializable {
      */
     @ExcelProperty(value = "供应状态", converter = ExcelDictConvert.class)
     @ExcelDictFormat(readConverterExp = "0=-暂停,,1=-正常...")
-    private String supplyStatus;
+    private Long supplyStatus;
 
     /**
      * 供应评分
@@ -413,5 +413,36 @@ public class SupplierInfoVo implements Serializable {
 
     private Date createTime;
 
+    private Long listedNum = 0L; // 上架产品数(默认值0)
+
+    private String brandName;
+
+    private String enterpriseScaleName;
+
+
+    private String SupplierTypeName;
+
+    /**
+     * 登记状态
+     */
+    private String registrationStatus;
+
+    /**
+     * 登记机关
+     */
+    private String registrationAuthority;
+
+    /**
+     * 成立日期
+     */
+    private Date establishmentDate;
+
+    /**
+     * 实缴资本
+     */
+    private String paidInCapital;
+
+
+
 
 }

+ 5 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SupplyAreaVo.java

@@ -11,7 +11,7 @@ import lombok.Data;
 import java.io.Serial;
 import java.io.Serializable;
 import java.util.Date;
-
+import java.util.List;
 
 
 /**
@@ -28,6 +28,8 @@ public class SupplyAreaVo implements Serializable {
     @Serial
     private static final long serialVersionUID = 1L;
 
+    private Long id;
+
     /**
      * 供应商编号(关联供应商主表)
      */
@@ -70,5 +72,7 @@ public class SupplyAreaVo implements Serializable {
     @ExcelDictFormat(readConverterExp = "1=省/直辖市,2=市,3=区县,4=街道/镇")
     private String level;
 
+    private List<SupplyAreaVo> areaList;
+
 
 }

+ 25 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteSupplierContractServiceImpl.java

@@ -0,0 +1,25 @@
+package org.dromara.customer.dubbo;
+
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.customer.api.RemoteSupplierContractService;
+import org.dromara.customer.service.ISupplierContractService;
+import org.springframework.stereotype.Service;
+
+/**
+ * author
+ * 时间:2026/1/23,9:24
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@DubboService
+public class RemoteSupplierContractServiceImpl implements RemoteSupplierContractService {
+
+    private final ISupplierContractService supplierContractService;
+    @Override
+    public int updateExpiredContractStatus() {
+        return supplierContractService.updateExpiredContractStatus();
+    }
+}

+ 25 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteSupplierInfoServiceImpl.java

@@ -0,0 +1,25 @@
+package org.dromara.customer.dubbo;
+
+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.service.ISupplierInfoService;
+import org.springframework.stereotype.Service;
+
+/**
+ * author
+ * 时间:2026/1/23,9:42
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@DubboService
+public class RemoteSupplierInfoServiceImpl implements RemoteSupplierInfoService {
+
+    private final ISupplierInfoService supplierInfoService;
+    @Override
+    public int updateIsDisable() {
+        return supplierInfoService.updateIsDisable();
+    }
+}

+ 10 - 9
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/enums/SupplierStatusEnum.java

@@ -6,20 +6,21 @@ package org.dromara.customer.enums;
  */
 public enum SupplierStatusEnum {
     // 枚举项:数据库值, 原始状态名, 展示文案
-    PENDING_REVIEW(0, "待审核", "待审核"),
-    OFFICIAL_SUPPLIER(1, "正式供应商", "生效"),
-    DISABLED(2, "停用", "停止合作"),
-    REVIEW_FAILED(3, "审核未通过", "审核不通过");
+    PENDING_REVIEW(0L, "待审核", "待审核"),
+    OFFICIAL_SUPPLIER(1L, "正式供应商", "生效"),
+    DISABLED(2L, "停用", "停止合作"),
+    REVIEW_FAILED(3L, "审核未通过", "审核不通过"),
+    REVIEW_UPDATED(4L,"待修改审核","待修改审核");
 
     // 数据库存储的数字值
-    private final Integer code;
+    private final Long code;
     // 原始状态名称(保留,便于后续追溯)
     private final String originalName;
     // 前端展示的文案
     private final String displayName;
 
     // 构造方法
-    SupplierStatusEnum(Integer code, String originalName, String displayName) {
+    SupplierStatusEnum(Long code, String originalName, String displayName) {
         this.code = code;
         this.originalName = originalName;
         this.displayName = displayName;
@@ -30,7 +31,7 @@ public enum SupplierStatusEnum {
      * @param code 数据库中的数字值(0/1/2/3)
      * @return 展示文案,无匹配时返回"未知状态"
      */
-    public static String getDisplayNameByCode(Integer code) {
+    public static String getDisplayNameByCode(Long code) {
         // 遍历枚举项,匹配code后返回对应的展示文案
         for (SupplierStatusEnum status : values()) {
             if (status.code.equals(code)) {
@@ -41,7 +42,7 @@ public enum SupplierStatusEnum {
     }
 
     // 可选:获取原始状态名(如需追溯)
-    public static String getOriginalNameByCode(Integer code) {
+    public static String getOriginalNameByCode(Long code) {
         for (SupplierStatusEnum status : values()) {
             if (status.code.equals(code)) {
                 return status.originalName;
@@ -51,7 +52,7 @@ public enum SupplierStatusEnum {
     }
 
     // getter方法
-    public Integer getCode() {
+    public Long getCode() {
         return code;
     }
 

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

@@ -0,0 +1,15 @@
+package org.dromara.customer.mapper;
+
+import org.dromara.customer.domain.SupplierBusinessInfo;
+import org.dromara.customer.domain.vo.SupplierBusinessInfoVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 供应商工商注册信息Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-22
+ */
+public interface SupplierBusinessInfoMapper extends BaseMapperPlus<SupplierBusinessInfo, SupplierBusinessInfoVo> {
+
+}

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

@@ -67,4 +67,6 @@ public interface IContractSupplyService extends IService<ContractSupply>{
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    int aprprove(ContractSupplyBo bo);
 }

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

@@ -0,0 +1,72 @@
+package org.dromara.customer.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.customer.domain.SupplierBusinessInfo;
+import org.dromara.customer.domain.vo.SupplierBusinessInfoVo;
+import org.dromara.customer.domain.bo.SupplierBusinessInfoBo;
+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-22
+ */
+public interface ISupplierBusinessInfoService extends IService<SupplierBusinessInfo>{
+
+    /**
+     * 查询供应商工商注册信息
+     *
+     * @param supplierId 主键
+     * @return 供应商工商注册信息
+     */
+    SupplierBusinessInfoVo queryById(Long supplierId);
+
+    /**
+     * 分页查询供应商工商注册信息列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 供应商工商注册信息分页列表
+     */
+    TableDataInfo<SupplierBusinessInfoVo> queryPageList(SupplierBusinessInfoBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的供应商工商注册信息列表
+     *
+     * @param bo 查询条件
+     * @return 供应商工商注册信息列表
+     */
+    List<SupplierBusinessInfoVo> queryList(SupplierBusinessInfoBo bo);
+
+    /**
+     * 新增供应商工商注册信息
+     *
+     * @param bo 供应商工商注册信息
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(SupplierBusinessInfoBo bo);
+
+    /**
+     * 修改供应商工商注册信息
+     *
+     * @param bo 供应商工商注册信息
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(SupplierBusinessInfoBo bo);
+
+    /**
+     * 校验并批量删除供应商工商注册信息信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    SupplierBusinessInfoVo getinformation(String enterpriseName);
+}

+ 7 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierContractService.java

@@ -72,5 +72,11 @@ public interface ISupplierContractService extends IService<SupplierContract>{
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
 
-
+    /**
+     * 更新过期合同状态
+     * 将合同到期时间早于当前时间的合同状态更新为已到期(2)
+     *
+     * @return 更新的记录数
+     */
+    int updateExpiredContractStatus();
 }

+ 2 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ISupplierInfoService.java

@@ -9,7 +9,6 @@ import org.dromara.customer.domain.vo.SupplierInfoVo;
 import org.dromara.customer.domain.bo.SupplierInfoBo;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
-import org.dromara.customer.domain.vo.SupplierInformationVo;
 
 import java.util.Collection;
 import java.util.List;
@@ -91,4 +90,6 @@ public interface ISupplierInfoService extends IService<SupplierInfo>{
 
 
     IPage<SupplierInfo> getSupplyCapacityList(SupplierAuthorizeBo bo, PageQuery pageQuery);
+
+    int updateIsDisable();
 }

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

@@ -25,7 +25,7 @@ public interface ISupplyAreaService extends IService<SupplyArea>{
      * @param id 主键
      * @return 供应区域
      */
-    SupplyAreaVo queryById(Long id);
+    List<SupplyAreaVo> queryById(Long id);
 
     /**
      * 分页查询供应区域列表

+ 119 - 6
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/ContractSupplyServiceImpl.java

@@ -1,7 +1,10 @@
 package org.dromara.customer.service.impl;
 
 import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import net.sf.jsqlparser.expression.LongValue;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.ObjectUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -13,9 +16,17 @@ 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.ContractSupplyProductVo;
 import org.dromara.customer.domain.vo.SupplierContractVo;
 import org.dromara.customer.enums.ContractSupplierStatusEnum;
 import org.dromara.customer.service.ISupplierInfoService;
+import org.dromara.product.api.RemoteContractProdcutService;
+import org.dromara.product.api.RemoteProductService;
+import org.dromara.product.api.domain.ContractProductDto;
+import org.dromara.product.api.domain.ProductVo;
+import org.springframework.beans.BeanUtils;
+import org.springframework.data.redis.core.StringRedisTemplate;
+import org.springframework.data.redis.core.ValueOperations;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.ContractSupplyBo;
 import org.dromara.customer.domain.vo.ContractSupplyVo;
@@ -23,7 +34,9 @@ import org.dromara.customer.domain.ContractSupply;
 import org.dromara.customer.mapper.ContractSupplyMapper;
 import org.dromara.customer.service.IContractSupplyService;
 
+import java.text.SimpleDateFormat;
 import java.util.*;
+import java.util.concurrent.TimeUnit;
 import java.util.stream.Collectors;
 
 /**
@@ -41,6 +54,16 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
 
     private final ISupplierInfoService supplierInfoService;
 
+    private final StringRedisTemplate redisTemplate;
+
+    private final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMdd");
+
+    @DubboReference
+    private final RemoteContractProdcutService remoteContractProdcutService;
+
+    @DubboReference
+    private final RemoteProductService remoteProductService;
+
     /**
      * 查询协议供货
      *
@@ -49,7 +72,26 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
      */
     @Override
     public ContractSupplyVo queryById(Long id){
-        return baseMapper.selectVoById(id);
+        ContractSupply contractSupply = getById(id);
+        ContractSupplyVo contractSupplyVo = MapstructUtils.convert(contractSupply, ContractSupplyVo.class);
+        List<ContractProductDto> contractProductDtos = remoteContractProdcutService.queryList(contractSupplyVo.getId());
+
+        List<ContractSupplyProductVo> contractProduct = new ArrayList<>();
+        if (contractProductDtos != null && !contractProductDtos.isEmpty()){
+            for (ContractProductDto dto : contractProductDtos){
+                ContractSupplyProductVo contractSupplyProductVo = new ContractSupplyProductVo();
+                BeanUtils.copyProperties(dto, contractSupplyProductVo);
+                contractProduct.add(contractSupplyProductVo);
+            }
+        }
+        if (contractProduct != null && !contractProduct.isEmpty()) {
+            for (ContractSupplyProductVo vo : contractProduct) {
+                ProductVo productDetail = remoteProductService.getProductDetail(vo.getProductId());
+                BeanUtils.copyProperties(productDetail, vo,"id");
+            }
+        }
+        contractSupplyVo.setContractProduct(contractProduct);
+        return contractSupplyVo;
     }
 
     /**
@@ -61,6 +103,12 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
      */
     @Override
     public TableDataInfo<ContractSupplyVo> queryPageList(ContractSupplyBo bo, PageQuery pageQuery) {
+        if (bo.getSupplierName()!=null){
+            LambdaQueryWrapper<SupplierInfo> lqw = Wrappers.lambdaQuery(SupplierInfo.class)
+                    .eq(SupplierInfo::getEnterpriseName, bo.getSupplierName());
+            SupplierInfo one = supplierInfoService.getOne(lqw);
+            bo.setSupplierId(one.getId());
+        }
         LambdaQueryWrapper<ContractSupply> lqw = buildQueryWrapper(bo);
         Page<ContractSupplyVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         setSupplierNames(result.getRecords());
@@ -177,10 +225,47 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
      */
     @Override
     public Boolean insertByBo(ContractSupplyBo bo) {
+        // 1. 生成 年月日+4位序号 的唯一编号
+        String contractSupplyNo = generateContractSupplyNo();
+
+        List<ContractProductDto> contractProduct = bo.getContractProduct();
+
         ContractSupply add = MapstructUtils.convert(bo, ContractSupply.class);
         validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        return flag;
+        add.setContractSupplyNo(contractSupplyNo);
+        add.setProductNumber((long)contractProduct.size());
+        add.setPriceCycle(0L);
+        boolean flag2 = baseMapper.insert(add) > 0;
+        Long id = add.getId();
+        contractProduct.forEach(product ->{
+            product.setContractSupplyNo(contractSupplyNo);
+            product.setContractSupplyId(id);
+        } );
+        boolean flag1 = remoteContractProdcutService.add(contractProduct);
+        //boolean flag2 = baseMapper.insert(add) > 0;
+        return flag1&&flag2;
+    }
+
+    /**
+     * 生成合同供货编号:年月日 + 4位序号(如 202601200001)
+     * @return 唯一编号
+     */
+    private String generateContractSupplyNo() {
+        // 步骤1:获取当天日期作为 Redis Key 前缀
+        String today = DATE_FORMAT.format(new Date());
+        String redisKey = "contract_supply:seq:" + today;
+
+        // 步骤2:Redis 原子自增(初始值为1,每次+1)
+        ValueOperations<String, String> valueOps = redisTemplate.opsForValue();
+        Long seq = valueOps.increment(redisKey, 1);
+
+        // 步骤3:首次生成时设置过期时间(2天,避免Key永久存在)
+        if (seq == 1) {
+            redisTemplate.expire(redisKey, 2, TimeUnit.DAYS);
+        }
+
+        // 步骤4:拼接编号,4位序号不足补0(如 1 → 0001)
+        return today + String.format("%04d", seq);
     }
 
     /**
@@ -191,9 +276,26 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
      */
     @Override
     public Boolean updateByBo(ContractSupplyBo bo) {
-        ContractSupply update = MapstructUtils.convert(bo, ContractSupply.class);
-        validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
+        List<ContractProductDto> contractProduct = bo.getContractProduct();
+
+        ContractSupply add = MapstructUtils.convert(bo, ContractSupply.class);
+        validEntityBeforeSave(add);
+        add.setProductNumber((long)contractProduct.size());
+        add.setPriceCycle(0L);
+        boolean flag1 = baseMapper.updateById(add)>0;
+        String contractSupplyNo = add.getContractSupplyNo();
+        Long id = add.getId();
+        boolean delete = remoteContractProdcutService.delete(add.getId());
+        boolean flag2=false;
+        if (delete){
+            contractProduct.forEach(product ->{
+                product.setContractSupplyNo(contractSupplyNo);
+                product.setContractSupplyId(id);
+            } );
+            flag2 = remoteContractProdcutService.add(contractProduct);
+        }
+        return flag1&&flag2;
+
     }
 
     /**
@@ -217,4 +319,15 @@ public class ContractSupplyServiceImpl  extends ServiceImpl<ContractSupplyMapper
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    @Override
+    public int aprprove(ContractSupplyBo bo) {
+        String status = bo.getStatus();
+        Long id = bo.getId();
+        LambdaUpdateWrapper<ContractSupply> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.eq(ContractSupply::getId, id)
+            .set(ContractSupply::getStatus, status);
+        return baseMapper.update(null, updateWrapper);
+
+    }
 }

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

@@ -102,6 +102,15 @@ public class SupplierAddressServiceImpl  extends ServiceImpl<SupplierAddressMapp
     public Boolean insertByBo(SupplierAddressBo bo) {
         SupplierAddress add = MapstructUtils.convert(bo, SupplierAddress.class);
         validEntityBeforeSave(add);
+        LambdaQueryWrapper<SupplierAddress> lqw = Wrappers.lambdaQuery();
+        lqw.select(SupplierAddress::getAddressNo)
+            .orderByDesc(SupplierAddress::getAddressNo)
+            .last("LIMIT 1");
+        SupplierAddress supplierAddress = baseMapper.selectOne(lqw);
+        String addressNo = supplierAddress.getAddressNo();
+        Long maxNo = Long.parseLong(addressNo);
+        String newAddressNo = String.valueOf(maxNo+1);
+        add.setAddressNo(newAddressNo);
         boolean flag = baseMapper.insert(add) > 0;
         if (flag) {
             bo.setId(add.getId());

+ 71 - 4
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierAuthorizeServiceImpl.java

@@ -19,6 +19,8 @@ import org.dromara.customer.domain.vo.SupplyAreaVo;
 import org.dromara.customer.service.ISupplierInfoService;
 import org.dromara.customer.service.ISupplyAreaService;
 import org.dromara.product.api.RemoteCategoryService;
+import org.dromara.product.api.RemoteProductService;
+import org.dromara.product.api.domain.RemoteProductBrand;
 import org.springframework.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.SupplierAuthorizeBo;
@@ -26,6 +28,7 @@ import org.dromara.customer.domain.vo.SupplierAuthorizeVo;
 import org.dromara.customer.domain.SupplierAuthorize;
 import org.dromara.customer.mapper.SupplierAuthorizeMapper;
 import org.dromara.customer.service.ISupplierAuthorizeService;
+import org.springframework.util.CollectionUtils;
 
 import java.util.*;
 import java.util.stream.Collectors;
@@ -50,6 +53,9 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
     @DubboReference
     private final RemoteCategoryService remoteCategoryService;
 
+    @DubboReference
+    private final RemoteProductService remoteProductService;
+
     /**
      * 查询供应能力查询
      *
@@ -92,7 +98,48 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
         //查询供应商信息
         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));
+
+        Set<Long> allBrandIds = new HashSet<>();
+        for (SupplierInfo record : records) {
+            String operatingBrand = record.getOperatingBrand();
+            if (StringUtils.isNotBlank(operatingBrand)) {
+                String[] brandIdStrs = operatingBrand.split(",");
+                for (String idStr : brandIdStrs) {
+                    try {
+                        Long brandId = Long.valueOf(idStr.trim());
+                        allBrandIds.add(brandId);
+                    } catch (NumberFormatException e) {
+                        // 兼容非法ID,跳过
+                        continue;
+                    }
+                }
+            }
+        }
+
+        final Map<Long, String> brandIdToNameMap = new HashMap<>();
+        if (!CollectionUtils.isEmpty(allBrandIds)) {
+            List<Long> brandIdList = new ArrayList<>(allBrandIds);
+            // 调用你的品牌查询接口
+            List<RemoteProductBrand> brandList = remoteProductService.getProductByBrandId(brandIdList);
+
+            if (!CollectionUtils.isEmpty(brandList)) {
+                brandIdToNameMap.putAll(
+                    brandList.stream()
+                        .collect(Collectors.toMap(
+                            RemoteProductBrand::getId,
+                            RemoteProductBrand::getBrandName,
+                            (existing, replacement) -> existing
+                        ))
+                );
+            }
+        }
+
+        Map<Long, String> supplierCategoryMap = records.stream()
+            .collect(Collectors.toMap(SupplierInfo::getId,
+                record -> record.getOperatingCategory() != null ? record.getOperatingCategory() : "",
+                (existing, replacement) -> existing
+            ));
+
         //查询供应品类
         Map<Long, String> supplierCategoryNameMap = supplierCategoryNamesMap(supplierCategoryMap);
         //查询授权品牌String拼接
@@ -104,8 +151,29 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
             BeanUtils.copyProperties(item, supplierAuthorizeVo);
             supplierAuthorizeVo.setSupplierName(item.getEnterpriseName());
             supplierAuthorizeVo.setSupplyBrand(item.getOperatingBrand());
-            supplierAuthorizeVo.setSupplyProCate(supplierCategoryNameMap.get(item.getId()));
-            supplierAuthorizeVo.setAuthBrand(supplierBrandMap.get(item.getId()));
+            supplierAuthorizeVo.setSupplierId(item.getId());
+            supplierAuthorizeVo.setSupplyProCate(supplierCategoryNameMap.getOrDefault(item.getId(),""));
+            supplierAuthorizeVo.setAuthBrand(supplierBrandMap.getOrDefault(item.getId(),""));
+
+            // 新增:转换品牌ID为名称拼接
+            String operatingBrand = item.getOperatingBrand();
+            if (StringUtils.isNotBlank(operatingBrand)) {
+                String brandNames = Arrays.stream(operatingBrand.split(","))
+                    .map(String::trim)
+                    .map(idStr -> {
+                        try {
+                            Long brandId = Long.valueOf(idStr);
+                            return brandIdToNameMap.getOrDefault(brandId, idStr);
+                        } catch (NumberFormatException e) {
+                            return idStr;
+                        }
+                    })
+                    .collect(Collectors.joining(","));
+                // 赋值到VO(需确保SupplierAuthorizeVo有brandName字段,无则新增)
+                supplierAuthorizeVo.setBrandName(brandNames);
+            } else {
+                supplierAuthorizeVo.setBrandName("");
+            }
             return supplierAuthorizeVo;
         }).collect(Collectors.toList());
         IPage<SupplierAuthorizeVo> voPage = new Page<>();
@@ -113,7 +181,6 @@ public class SupplierAuthorizeServiceImpl  extends ServiceImpl<SupplierAuthorize
         // 设置转换后的Vo列表
         voPage.setRecords(collect);
         return TableDataInfo.build(voPage);
-
     }
 
     private Map<Long, String> supplierBrandMap(List<Long> ids){

+ 209 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierBusinessInfoServiceImpl.java

@@ -0,0 +1,209 @@
+package org.dromara.customer.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.DateUtils;
+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.dromara.customer.utils.qcc.QccUtils;
+import org.dromara.customer.utils.qcc.domain.CompanyInfoResponse;
+import org.dromara.customer.utils.qcc.domain.Result;
+import org.springframework.stereotype.Service;
+import org.dromara.customer.domain.bo.SupplierBusinessInfoBo;
+import org.dromara.customer.domain.vo.SupplierBusinessInfoVo;
+import org.dromara.customer.domain.SupplierBusinessInfo;
+import org.dromara.customer.mapper.SupplierBusinessInfoMapper;
+import org.dromara.customer.service.ISupplierBusinessInfoService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 供应商工商注册信息Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-22
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class SupplierBusinessInfoServiceImpl  extends ServiceImpl<SupplierBusinessInfoMapper, SupplierBusinessInfo> implements ISupplierBusinessInfoService {
+
+    private final SupplierBusinessInfoMapper baseMapper;
+
+    /**
+     * 查询供应商工商注册信息
+     *
+     * @param supplierId 主键
+     * @return 供应商工商注册信息
+     */
+    @Override
+    public SupplierBusinessInfoVo queryById(Long supplierId){
+        return baseMapper.selectVoById(supplierId);
+    }
+
+    /**
+     * 分页查询供应商工商注册信息列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 供应商工商注册信息分页列表
+     */
+    @Override
+    public TableDataInfo<SupplierBusinessInfoVo> queryPageList(SupplierBusinessInfoBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<SupplierBusinessInfo> lqw = buildQueryWrapper(bo);
+        Page<SupplierBusinessInfoVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的供应商工商注册信息列表
+     *
+     * @param bo 查询条件
+     * @return 供应商工商注册信息列表
+     */
+    @Override
+    public List<SupplierBusinessInfoVo> queryList(SupplierBusinessInfoBo bo) {
+        LambdaQueryWrapper<SupplierBusinessInfo> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<SupplierBusinessInfo> buildQueryWrapper(SupplierBusinessInfoBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<SupplierBusinessInfo> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(SupplierBusinessInfo::getSupplierId);
+        lqw.like(StringUtils.isNotBlank(bo.getBusinessName()), SupplierBusinessInfo::getBusinessName, bo.getBusinessName());
+        lqw.eq(StringUtils.isNotBlank(bo.getSocialCreditCode()), SupplierBusinessInfo::getSocialCreditCode, bo.getSocialCreditCode());
+        lqw.like(StringUtils.isNotBlank(bo.getLegalPersonName()), SupplierBusinessInfo::getLegalPersonName, bo.getLegalPersonName());
+        lqw.eq(StringUtils.isNotBlank(bo.getRegisteredCapital()), SupplierBusinessInfo::getRegisteredCapital, bo.getRegisteredCapital());
+        lqw.eq(StringUtils.isNotBlank(bo.getPaidInCapital()), SupplierBusinessInfo::getPaidInCapital, bo.getPaidInCapital());
+        lqw.eq(bo.getEstablishmentDate() != null, SupplierBusinessInfo::getEstablishmentDate, bo.getEstablishmentDate());
+        lqw.eq(bo.getRevocationDate() != null, SupplierBusinessInfo::getRevocationDate, bo.getRevocationDate());
+        lqw.eq(StringUtils.isNotBlank(bo.getRegistrationStatus()), SupplierBusinessInfo::getRegistrationStatus, bo.getRegistrationStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getRegistrationAuthority()), SupplierBusinessInfo::getRegistrationAuthority, bo.getRegistrationAuthority());
+        lqw.eq(StringUtils.isNotBlank(bo.getBussinessRange()), SupplierBusinessInfo::getBussinessRange, bo.getBussinessRange());
+        lqw.eq(StringUtils.isNotBlank(bo.getBusinessLicense()), SupplierBusinessInfo::getBusinessLicense, bo.getBusinessLicense());
+        lqw.eq(StringUtils.isNotBlank(bo.getBusinessAddress()), SupplierBusinessInfo::getBusinessAddress, bo.getBusinessAddress());
+        return lqw;
+    }
+
+    /**
+     * 新增供应商工商注册信息
+     *
+     * @param bo 供应商工商注册信息
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(SupplierBusinessInfoBo bo) {
+        SupplierBusinessInfo add = MapstructUtils.convert(bo, SupplierBusinessInfo.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setSupplierId(add.getSupplierId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改供应商工商注册信息
+     *
+     * @param bo 供应商工商注册信息
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(SupplierBusinessInfoBo bo) {
+        SupplierBusinessInfo update = MapstructUtils.convert(bo, SupplierBusinessInfo.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(SupplierBusinessInfo 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 SupplierBusinessInfoVo getinformation(String enterpriseName) {
+        // 1. 先查本地数据库
+        LambdaQueryWrapper<SupplierBusinessInfo> query = new LambdaQueryWrapper<SupplierBusinessInfo>()
+            .eq(SupplierBusinessInfo::getBusinessName, enterpriseName)
+            .last("LIMIT 1");
+
+        List<SupplierBusinessInfoVo> list = baseMapper.selectVoList(query);
+        if (!list.isEmpty()) {
+            return list.get(0);
+        }
+
+        // 2. 调用企查查接口
+        CompanyInfoResponse response = QccUtils.getCompanyInfo(enterpriseName);
+        if (response == null || response.getResult() == null) {
+            return null; // 或抛异常,根据业务需求
+        }
+
+        // 3. 映射 QCC 数据到实体(注意:不设置 businessLicense)
+        Result result = response.getResult();
+        SupplierBusinessInfo entity = new SupplierBusinessInfo();
+
+        entity.setBusinessName(result.getName());
+        entity.setSocialCreditCode(result.getCreditCode());
+        entity.setLegalPersonName(result.getOperName());
+
+        // 注册资本:拼接数值 + 单位(如 "101万元")
+        String regCap = result.getRegisteredCapital();
+        String regUnit = result.getRegisteredCapitalUnit();
+        entity.setRegisteredCapital(
+            StringUtils.isNotBlank(regCap) && StringUtils.isNotBlank(regUnit)
+                ? regCap + regUnit
+                : regCap
+        );
+
+        // 实缴资本(类似处理)
+        String paidCap = result.getPaidUpCapital();
+        String paidUnit = result.getPaidUpCapitalUnit();
+        entity.setPaidInCapital(
+            StringUtils.isNotBlank(paidCap) && StringUtils.isNotBlank(paidUnit)
+                ? paidCap + paidUnit
+                : paidCap
+        );
+
+        // 日期转换(注意时区和格式)
+        entity.setEstablishmentDate(DateUtils.parseDate(result.getStartDate()));
+        // revocationDate 暂不处理,留 null
+        entity.setRevocationDate(null);
+
+        entity.setRegistrationStatus(result.getStatus());
+        entity.setRegistrationAuthority(result.getBelongOrg());
+        entity.setBussinessRange(result.getScope());
+        entity.setBusinessAddress(result.getAddress());
+
+        // 关键:不设置 businessLicense!保留为 null(由用户后续上传)
+        entity.setBusinessLicense(null);
+
+        // 5. 转 VO 返回
+        return MapstructUtils.convert(entity, SupplierBusinessInfoVo.class);
+    }
+}

+ 19 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContactServiceImpl.java

@@ -13,6 +13,7 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.customer.controller.SupplierInfoController;
 import org.dromara.customer.domain.SupplierInfo;
+import org.dromara.customer.domain.vo.SupplierInformationVo;
 import org.dromara.customer.service.ISupplierInfoService;
 import org.dromara.system.api.RemoteUserService;
 import org.dromara.system.api.domain.bo.RemoteUserBo;
@@ -55,6 +56,10 @@ public class SupplierContactServiceImpl  extends ServiceImpl<SupplierContactMapp
      */
     @Override
     public SupplierContactVo queryById(Long id){
+        SupplierContactVo supplierContactVo = baseMapper.selectVoById(id);
+        SupplierInfo one = supplierInfoService.getOne(new LambdaQueryWrapper<SupplierInfo>().eq(SupplierInfo::getId, supplierContactVo.getSupplierId()));
+        one.getEnterpriseName();
+        supplierContactVo.setSupplierName(one.getEnterpriseName());
         return baseMapper.selectVoById(id);
     }
 
@@ -67,6 +72,10 @@ public class SupplierContactServiceImpl  extends ServiceImpl<SupplierContactMapp
      */
     @Override
     public TableDataInfo<SupplierContactVo> queryPageList(SupplierContactBo bo, PageQuery pageQuery) {
+        if (bo.getSupplierName()!= null){
+            SupplierInfo one = supplierInfoService.getOne(new LambdaQueryWrapper<SupplierInfo>().eq(SupplierInfo::getEnterpriseName, bo.getSupplierName()));
+            bo.setSupplierId(one.getId());
+        }
         LambdaQueryWrapper<SupplierContact> lqw = buildQueryWrapper(bo);
         Page<SupplierContactVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         setSupplierNames(result.getRecords());
@@ -152,6 +161,16 @@ public class SupplierContactServiceImpl  extends ServiceImpl<SupplierContactMapp
     public Boolean insertByBo(SupplierContactBo bo) {
         SupplierContact add = MapstructUtils.convert(bo, SupplierContact.class);
         validEntityBeforeSave(add);
+
+        // 查询最大的用户编号
+        LambdaQueryWrapper<SupplierContact> lqw = Wrappers.lambdaQuery();
+        lqw.select(SupplierContact::getUserNo)
+            .orderByDesc(SupplierContact::getUserNo)
+            .last("LIMIT 1");
+        SupplierContact maxContact = baseMapper.selectOne(lqw);
+        String maxUserNo = maxContact.getUserNo();
+        long l = Long.parseLong(maxUserNo) + 1;
+        add.setUserNo(String.valueOf(l));
         boolean flag = baseMapper.insert(add) > 0;
         return flag;
     }

+ 124 - 65
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierContractServiceImpl.java

@@ -1,5 +1,6 @@
 package org.dromara.customer.service.impl;
 
+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.dromara.common.core.utils.MapstructUtils;
@@ -11,10 +12,12 @@ 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.common.redis.utils.RedisUtils;
 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.data.redis.core.StringRedisTemplate;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.SupplierContractBo;
 import org.dromara.customer.domain.vo.SupplierContractVo;
@@ -22,6 +25,8 @@ import org.dromara.customer.domain.SupplierContract;
 import org.dromara.customer.mapper.SupplierContractMapper;
 import org.dromara.customer.service.ISupplierContractService;
 
+import java.time.LocalDate;
+import java.time.format.DateTimeFormatter;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -40,6 +45,14 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
 
     private final ISupplierInfoService supplierInfoService;
 
+    private final StringRedisTemplate redisTemplate;
+
+    private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMdd");
+    // 合同编号固定前缀
+    private static final String CONTRACT_NO_PREFIX = "contractNo";
+    // Redis Key前缀
+    private static final String REDIS_KEY_PREFIX = "contract_no:";
+
     /**
      * 查询合同管理
      *
@@ -60,76 +73,92 @@ 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());
+        // 首先从SupplierInfo表进行分页查询
+        LambdaQueryWrapper<SupplierInfo> supplierInfoWrapper = Wrappers.lambdaQuery();
+        if (bo.getSupplierName() != null) {
+            supplierInfoWrapper.eq(SupplierInfo::getEnterpriseName, bo.getSupplierName());
         }
-        LambdaQueryWrapper<SupplierContract> lqw = buildQueryWrapper(bo);
-        // 查询所有符合条件的记录
-        List<SupplierContract> allRecords = baseMapper.selectList(lqw);
-        // 获取当前时间(用于判断合同是否过期)
-        Date now = new Date();
-
-        // 按供应商ID分组,同时统计总数、有效数、失效数
-        Map<Long, ContractCountDTO> countMap = allRecords.stream()
-            .collect(Collectors.groupingBy(
-                SupplierContract::getSupplierId,
-                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();
+        if (bo.getSupplierId()!=null){
+            supplierInfoWrapper.eq(SupplierInfo::getId, bo.getSupplierId());
+        }
+
+        // 添加其他SupplierInfo表的查询条件
+        supplierInfoWrapper.orderByDesc(SupplierInfo::getSupplierNo);
+
+        // 执行分页查询供应商信息
+        Page<SupplierInfo> supplierPage = new Page<>(pageQuery.getPageNum(), pageQuery.getPageSize());
+        IPage<SupplierInfo> supplierInfoPage = supplierInfoService.page(supplierPage, supplierInfoWrapper);
+        List<SupplierInfo> supplierInfoList = supplierInfoPage.getRecords();
+
+        // 获取所有供应商ID,用于后续查询合同统计信息
+        List<Long> supplierIds = supplierInfoList.stream()
+            .map(SupplierInfo::getId)
+            .collect(Collectors.toList());
+
 
+
+        // 查询所有供应商的合同统计信息
+        Map<Long, ContractCountDTO> contractStatsMap = new HashMap<>();
+        if (!supplierIds.isEmpty()) {
+            // 查询所有相关合同
+            LambdaQueryWrapper<SupplierContract> contractWrapper = Wrappers.lambdaQuery();
+            contractWrapper.in(SupplierContract::getSupplierId, supplierIds);
+            List<SupplierContract> allContracts = baseMapper.selectList(contractWrapper);
+
+            // 获取当前时间(用于判断合同是否过期)
+            Date now = new Date();
+
+            // 按供应商ID分组统计合同信息
+            contractStatsMap = allContracts.stream()
+                .collect(Collectors.groupingBy(
+                    SupplierContract::getSupplierId,
+                    Collectors.collectingAndThen(
+                        Collectors.toList(),
+                        list -> {
+                            // 统计总数
+                            long total = list.size();
+                            // 统计有效期内合同数(状态为已生效 且 到期时间晚于当前时间)
+                            long validCount = list.stream()
+                                .filter(contract ->
+                                    2L != (contract.getContractStatus())
+                                        && contract.getContractEndTime() != null && contract.getContractEndTime().after(now)
+                                ).count();
+                            // 统计失效合同数(总数 - 有效数)
+                            long invalidCount = total - validCount;
+                            return new ContractCountDTO(total, validCount, invalidCount);
+                        }
+                    )
+                ));
+        }
+
+        // 将供应商信息和合同统计信息组合成VO列表
+        final Map<Long, ContractCountDTO> finalContractStatsMap = contractStatsMap; // 创建final副本
+        List<SupplierContractVo> contractStats = supplierInfoList.stream()
+            .map(supplierInfo -> {
                 SupplierContractVo vo = new SupplierContractVo();
-                vo.setSupplierId(supplierId);
-                // 合同总数
+                vo.setSupplierId(supplierInfo.getId());
+                vo.setSupplierNo(supplierInfo.getSupplierNo());
+                vo.setSupplierName(supplierInfo.getEnterpriseName());
+
+                // 获取合同统计信息,如果没有则创建默认值为0的统计对象
+                ContractCountDTO defaultCountDTO = new ContractCountDTO(0, 0, 0);
+                ContractCountDTO countDTO = finalContractStatsMap.getOrDefault(supplierInfo.getId(),
+                    defaultCountDTO);
+
+                // 设置合同数统计
                 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()))
             .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 = start > end ? List.of() : contractStats.subList(start, end);
-
+        // 构建分页结果
         Page<SupplierContractVo> result = new Page<>();
-        result.setRecords(pagedResult);
-        result.setTotal(total);
-        result.setSize(pageQuery.getPageSize());
-        result.setCurrent(pageQuery.getPageNum());
+        result.setRecords(contractStats);
+        result.setTotal(supplierInfoPage.getTotal());
+        result.setSize(supplierInfoPage.getSize());
+        result.setCurrent(supplierInfoPage.getCurrent());
         return TableDataInfo.build(result);
     }
 
@@ -195,10 +224,11 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
         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.ge(bo.getContractStartTime() !=null, SupplierContract::getContractStartTime, bo.getContractStartTime());
+        lqw.le(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());
+        lqw.eq(bo.getContractType() !=null, SupplierContract::getContractType, bo.getContractType());
         return lqw;
     }
 
@@ -213,13 +243,33 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
         SupplierContract add = MapstructUtils.convert(bo, SupplierContract.class);
         validEntityBeforeSave(add);
         add.setContractStatus(0L);
+
+        // 1. 生成当日Redis Key(按日期分桶)
+        String today = LocalDate.now().format(DATE_FORMATTER);
+        String redisKey = REDIS_KEY_PREFIX + today;
+
+        // 2. Redis原子自增,保证并发安全(初始值为1,每次+1)
+        Long incrementNum = redisTemplate.opsForValue().increment(redisKey, 1);
+
+        // 3. 自增数字补零为4位(比如1→0001,12→0012,123→0123)
+        String seqNum = String.format("%04d", incrementNum);
+
+        // 4. 拼接最终合同编号
+        String contractNo =today + seqNum;
+        add.setContractNo(contractNo); // 设置到实体中
+
+        // 5. 设置Redis Key过期时间(可选,避免Key堆积,比如保留7天)
+        redisTemplate.expire(redisKey, 1, java.util.concurrent.TimeUnit.DAYS);
+
+        // 6. 执行数据库插入操作(这里补充你的插入逻辑)
+        // supplierContractMapper.insert(add);
         boolean flag = baseMapper.insert(add) > 0;
-        if (flag) {
-//            bo.setId(add.getId());
-        }
+
         return flag;
+
     }
 
+
     /**
      * 修改合同管理
      *
@@ -255,5 +305,14 @@ public class SupplierContractServiceImpl  extends ServiceImpl<SupplierContractMa
         return baseMapper.deleteByIds(ids) > 0;
     }
 
-
+    @Override
+    public int updateExpiredContractStatus() {
+        // 创建更新条件:合同到期时间小于当前时间且合同状态不是已到期、已终止或已作废
+        LambdaUpdateWrapper<SupplierContract> updateWrapper = new LambdaUpdateWrapper<>();
+        updateWrapper.lt(SupplierContract::getContractEndTime, new Date()); // 合同到期时间小于当前时间
+        updateWrapper.notIn(SupplierContract::getContractStatus, 2L); // 不是已到期、已终止或已作废状态
+        updateWrapper.set(SupplierContract::getContractStatus, 2L); // 设置为已到期状态
+        // 执行更新操作
+        return baseMapper.update(null, updateWrapper);
+    }
 }

Разница между файлами не показана из-за своего большого размера
+ 911 - 64
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierInfoServiceImpl.java


+ 5 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplierProcurementServiceImpl.java

@@ -106,7 +106,11 @@ public class SupplierProcurementServiceImpl  extends ServiceImpl<SupplierProcure
     public Boolean updateByBo(SupplierProcurementBo bo) {
         SupplierProcurement update = MapstructUtils.convert(bo, SupplierProcurement.class);
         validEntityBeforeSave(update);
-        return baseMapper.updateById(update) > 0;
+        LambdaQueryWrapper<SupplierProcurement> lqw = Wrappers.lambdaQuery();
+        lqw.eq(SupplierProcurement::getSupplierId, bo.getSupplierId());
+
+        int result = baseMapper.update(update, lqw);
+        return result > 0;
     }
 
     /**

+ 81 - 11
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SupplyAreaServiceImpl.java

@@ -10,17 +10,17 @@ 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.beans.BeanUtils;
 import org.springframework.stereotype.Service;
 import org.dromara.customer.domain.bo.SupplyAreaBo;
 import org.dromara.customer.domain.vo.SupplyAreaVo;
 import org.dromara.customer.domain.SupplyArea;
 import org.dromara.customer.mapper.SupplyAreaMapper;
 import org.dromara.customer.service.ISupplyAreaService;
+import org.springframework.util.CollectionUtils;
 
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 供应区域Service业务层处理
@@ -42,8 +42,53 @@ public class SupplyAreaServiceImpl  extends ServiceImpl<SupplyAreaMapper, Supply
      * @return 供应区域
      */
     @Override
-    public SupplyAreaVo queryById(Long id){
-        return baseMapper.selectVoById(id);
+    public List<SupplyAreaVo> queryById(Long id){
+        // 1. 基础查询:获取该供应商下所有的区域数据(扁平列表)
+        LambdaQueryWrapper<SupplyArea> queryWrapper = new LambdaQueryWrapper<>();
+        queryWrapper.eq(SupplyArea::getSupplierId, id);
+        List<SupplyAreaVo> flatList = baseMapper.selectVoList(queryWrapper);
+        // 2. 判空:如果没有数据,直接返回空列表
+        if (CollectionUtils.isEmpty(flatList)) {
+            return new ArrayList<>();
+        }
+
+        // 3. 数据分组&构建树形结构
+        // 3.1 分离省级(level=1)和市级(level=2)数据
+        List<SupplyAreaVo> provinceList = flatList.stream()
+            .filter(vo -> "1".equals(vo.getLevel())) // 筛选省级
+            .collect(Collectors.toList());
+
+        List<SupplyAreaVo> cityList = flatList.stream()
+            .filter(vo -> "2".equals(vo.getLevel())) // 筛选市级
+            .collect(Collectors.toList());
+
+        // 3.2 构建父级编码到省级VO的映射(方便快速匹配)
+        Map<String, SupplyAreaVo> provinceMap = provinceList.stream()
+            .collect(Collectors.toMap(
+                SupplyAreaVo::getAreaCode, // key:省级区域编码(如CN34)
+                vo -> vo,                  // value:省级VO对象
+                (existing, replacement) -> existing // 避免重复编码覆盖
+            ));
+
+        // 3.3 遍历市级数据,挂载到对应的省级父节点中
+        for (SupplyAreaVo cityVo : cityList) {
+            // 市级的parentCode(上级编码)对应省级的areaCode
+            String parentAreaCode = cityVo.getParentCode(); // 注意类型转换(根据你的实际字段调整)
+
+            // 找到对应的省级父节点
+            SupplyAreaVo parentProvince = provinceMap.get(parentAreaCode);
+            if (parentProvince != null) {
+                // 初始化父节点的areaList(避免空指针)
+                if (parentProvince.getAreaList() == null) {
+                    parentProvince.setAreaList(new ArrayList<>());
+                }
+                // 将市级VO添加到父节点的areaList中
+                parentProvince.getAreaList().add(cityVo);
+            }
+        }
+
+        // 4. 返回最终的树形结构(仅返回省级列表,市级已挂载到对应父节点)
+        return provinceList;
     }
 
     /**
@@ -80,7 +125,7 @@ public class SupplyAreaServiceImpl  extends ServiceImpl<SupplyAreaMapper, Supply
         lqw.eq(bo.getSupplierId() != null, SupplyArea::getSupplierId, bo.getSupplierId());
         lqw.eq(StringUtils.isNotBlank(bo.getAreaCode()), SupplyArea::getAreaCode, bo.getAreaCode());
         lqw.like(StringUtils.isNotBlank(bo.getAreaName()), SupplyArea::getAreaName, bo.getAreaName());
-        lqw.eq(StringUtils.isNotBlank(bo.getParentCode()), SupplyArea::getParentCode, bo.getParentCode());
+        lqw.eq(bo.getParentCode()!=null, SupplyArea::getParentCode, bo.getParentCode());
         lqw.eq(StringUtils.isNotBlank(bo.getLevel()), SupplyArea::getLevel, bo.getLevel());
         return lqw;
     }
@@ -93,10 +138,35 @@ public class SupplyAreaServiceImpl  extends ServiceImpl<SupplyAreaMapper, Supply
      */
     @Override
     public Boolean insertByBo(SupplyAreaBo bo) {
-        SupplyArea add = MapstructUtils.convert(bo, SupplyArea.class);
-        validEntityBeforeSave(add);
-        boolean flag = baseMapper.insert(add) > 0;
-        return flag;
+        // 1. 校验核心参数(避免空指针)
+        if (bo == null || bo.getSupplierId() == null) {
+            throw new IllegalArgumentException("供应商ID不能为空");
+        }
+        List<SupplyAreaBo> areaList = bo.getAreaList();
+        if (areaList == null || areaList.isEmpty()) {
+            return true;
+        }
+
+        // 2. 遍历区域列表,为每个对象赋值supplierId和supplyNo
+        Long supplierId = bo.getSupplierId();
+        int delete = baseMapper.delete(new LambdaQueryWrapper<SupplyArea>().eq(SupplyArea::getSupplierId, supplierId));
+        String supplyNo = bo.getSupplyNo(); // 如果需要的话也赋值
+        List<SupplyArea> supplyAreas = new ArrayList<>();
+        for (SupplyAreaBo areaBo : areaList) {
+            SupplyArea supplyArea = new SupplyArea();
+            BeanUtils.copyProperties(areaBo, supplyArea);
+            // 核心:给每个区域对象设置供应商ID
+            supplyArea.setSupplierId(supplierId);
+            supplyArea.setSupplyNo(supplyNo);
+            supplyAreas.add(supplyArea);
+        }
+
+        // 3. 执行批量插入操作
+        boolean insertCount = baseMapper.insertBatch(supplyAreas);
+
+        // 4. 判断插入结果(插入数量和列表数量一致则返回成功)
+        return insertCount;
+
     }
 
     /**

+ 7 - 0
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SupplierBusinessInfoMapper.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.SupplierBusinessInfoMapper">
+
+</mapper>

+ 10 - 0
ruoyi-modules/ruoyi-job/pom.xml

@@ -22,6 +22,16 @@
             <artifactId>ruoyi-common-nacos</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-nacos</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
+
         <!-- RuoYi Common Log -->
         <dependency>
             <groupId>org.dromara</groupId>

+ 35 - 0
ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/SupplierContractJobTask.java

@@ -0,0 +1,35 @@
+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.springframework.stereotype.Component;
+
+/**
+ * author
+ * 时间:2026/1/23,9:02
+ */
+@Component
+@JobExecutor(name = "SupplierContractJobTask")
+@RequiredArgsConstructor
+public class SupplierContractJobTask {
+
+    @DubboReference
+    private final RemoteSupplierContractService remoteSupplierContractService;
+    public ExecuteResult jobExecute(JobArgs jobArgs){
+        // 更新过期合同状态
+        int i = remoteSupplierContractService.updateExpiredContractStatus();
+        if (i > 0){
+            SnailJobLog.REMOTE.info("合同状态更新完成");
+        }else {
+            SnailJobLog.REMOTE.info("合同状态更新失败");
+        }
+        return ExecuteResult.success("合同状态更新完成");
+    }
+
+}

+ 32 - 0
ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/SupplierInfoJobTask.java

@@ -0,0 +1,32 @@
+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.RemoteSupplierInfoService;
+import org.springframework.stereotype.Component;
+
+/**
+ * author
+ * 时间:2026/1/23,9:38
+ */
+@Component
+@JobExecutor(name = "SupplierInfoJobTask")
+@RequiredArgsConstructor
+public class SupplierInfoJobTask {
+
+    @DubboReference
+    private final RemoteSupplierInfoService remoteSupplierInfoService;
+    public ExecuteResult jobExecute(JobArgs jobArgs){
+        int i = remoteSupplierInfoService.updateIsDisable();
+        if (i > 0){
+            SnailJobLog.REMOTE.info("供应商信息更新完成");
+        }else {
+            SnailJobLog.REMOTE.info("供应商信息更新失败");
+        }
+        return ExecuteResult.success("供应商信息更新完成");
+    }
+}

+ 23 - 0
ruoyi-modules/ruoyi-job/src/main/java/org/dromara/job/snailjob/TestTask.java

@@ -0,0 +1,23 @@
+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 lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+/**
+ * author
+ * 时间:2026/1/23,10:09
+ */
+@Component
+@JobExecutor(name = "TestTask")
+@Slf4j
+public class TestTask {
+
+    public ExecuteResult jobExecute(JobArgs jobArgs) {
+        log.info("进行测试任务");
+        return ExecuteResult.success("测试任务成功");
+    }
+
+}

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

@@ -0,0 +1,106 @@
+package org.dromara.product.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.product.domain.vo.ContractProductVo;
+import org.dromara.product.domain.bo.ContractProductBo;
+import org.dromara.product.service.IContractProductService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 合同产品关联
+ * 前端访问路由地址为:/product/contracproduct
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/contracproduct")
+public class ContractProductController extends BaseController {
+
+    private final IContractProductService contractProductService;
+
+    /**
+     * 查询合同产品关联列表
+     */
+    @SaCheckPermission("product:contracproduct:list")
+    @GetMapping("/list")
+    public TableDataInfo<ContractProductVo> list(ContractProductBo bo, PageQuery pageQuery) {
+        return contractProductService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出合同产品关联列表
+     */
+    @SaCheckPermission("product:contracproduct:export")
+    @Log(title = "合同产品关联", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(ContractProductBo bo, HttpServletResponse response) {
+        List<ContractProductVo> list = contractProductService.queryList(bo);
+        ExcelUtil.exportExcel(list, "合同产品关联", ContractProductVo.class, response);
+    }
+
+    /**
+     * 获取合同产品关联详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("product:contracproduct:query")
+    @GetMapping("/{id}")
+    public R<ContractProductVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(contractProductService.queryById(id));
+    }
+
+    /**
+     * 新增合同产品关联
+     */
+    @SaCheckPermission("product:contracproduct:add")
+    @Log(title = "合同产品关联", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@RequestBody ContractProductBo bo) {
+        return toAjax(contractProductService.insertByBo(bo));
+    }
+
+    /**
+     * 修改合同产品关联
+     */
+    @SaCheckPermission("product:contracproduct:edit")
+    @Log(title = "合同产品关联", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody ContractProductBo bo) {
+        return toAjax(contractProductService.updateByBo(bo));
+    }
+
+    /**
+     * 删除合同产品关联
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("product:contracproduct:remove")
+    @Log(title = "合同产品关联", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(contractProductService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

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

@@ -46,6 +46,9 @@ public class ProductBrandController extends BaseController {
         return productBrandService.queryPageList(bo, pageQuery);
     }
 
+
+
+
     /**
      * 导出产品品牌信息列表
      */

+ 3 - 4
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductCategoryController.java

@@ -56,10 +56,9 @@ public class ProductCategoryController extends BaseController {
      */
     @GetMapping("/getProductCategoryList")
     public R<List<ProductCategoryVo>>getProductCategoryList() {
-        LambdaQueryWrapper<ProductCategory> queryWrapper = new LambdaQueryWrapper<>();
-        queryWrapper.eq(ProductCategory::getClassLevel, "1");
-        List<ProductCategory> list = productCategoryService.list(queryWrapper);
-        List<ProductCategoryVo> productCategoryVos = BeanUtil.copyToList(list, ProductCategoryVo.class);
+        ProductCategoryBo bo = new ProductCategoryBo();
+        bo.setClassLevel(1L);
+        List<ProductCategoryVo> productCategoryVos = productCategoryService.queryList(bo);
         return R.ok(productCategoryVos);
     }
 

+ 86 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ContractProduct.java

@@ -0,0 +1,86 @@
+package org.dromara.product.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 合同产品关联对象 contract_product
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("contract_product")
+public class ContractProduct extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 合同供货编号
+     */
+    private String contractSupplyNo;
+
+    /**
+     * 合同供货Id
+     */
+    private Long contractSupplyId;
+    /**
+     * 产品编号
+     */
+    private String productNo;
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 供货周期(单位:天/月,根据业务定义)
+     */
+    private Long supplyCycle;
+
+    /**
+     * 库存属性
+     */
+    private String inventoryProperties;
+
+    /**
+     * 最小供货量
+     */
+    private Long minSupply;
+
+    /**
+     * 报价(支持大文本)
+     */
+    private String offerPrice;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

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

@@ -0,0 +1,74 @@
+package org.dromara.product.domain.bo;
+
+import org.dromara.product.domain.ContractProduct;
+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.*;
+
+/**
+ * 合同产品关联业务对象 contract_product
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = ContractProduct.class, reverseConvertGenerate = false)
+public class ContractProductBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 合同供货编号
+     */
+    private String contractSupplyNo;
+
+    /**
+     * 合同供货Id
+     */
+    private String contractSupplyId;
+
+    /**
+     * 产品编号
+     */
+    private String productNo;
+
+    /**
+     * 产品id
+     */
+    private Long productId;
+
+    /**
+     * 供货周期(单位:天/月,根据业务定义)
+     */
+    private Long supplyCycle;
+
+    /**
+     * 库存属性
+     */
+    private String inventoryProperties;
+
+    /**
+     * 最小供货量
+     */
+    private Long minSupply;
+
+    /**
+     * 报价(支持大文本)
+     */
+    private String offerPrice;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+
+}

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

@@ -0,0 +1,94 @@
+package org.dromara.product.domain.vo;
+
+import org.dromara.product.domain.ContractProduct;
+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;
+
+
+
+/**
+ * 合同产品关联视图对象 contract_product
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = ContractProduct.class)
+public class ContractProductVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 合同供货编号
+     */
+    @ExcelProperty(value = "合同供货编号")
+    private String contractSupplyNo;
+
+    /**
+     * 合同供货Id
+     */
+    private Long contractSupplyId;
+
+    /**
+     * 产品编号
+     */
+    @ExcelProperty(value = "产品编号")
+    private String productNo;
+
+    /**
+     * 产品id
+     */
+    @ExcelProperty(value = "产品id")
+    private Long productId;
+
+    /**
+     * 供货周期(单位:天/月,根据业务定义)
+     */
+    @ExcelProperty(value = "供货周期", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "单=位:天/月,根据业务定义")
+    private Long supplyCycle;
+
+    /**
+     * 库存属性
+     */
+    @ExcelProperty(value = "库存属性")
+    private String inventoryProperties;
+
+    /**
+     * 最小供货量
+     */
+    @ExcelProperty(value = "最小供货量")
+    private Long minSupply;
+
+    /**
+     * 报价(支持大文本)
+     */
+    @ExcelProperty(value = "报价", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "支=持大文本")
+    private String offerPrice;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+
+}

+ 67 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteContractProductServiceImpl.java

@@ -0,0 +1,67 @@
+package org.dromara.product.dubbo;
+
+import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.product.api.RemoteContractProdcutService;
+import org.dromara.product.api.domain.ContractProductDto;
+import org.dromara.product.domain.ContractProduct;
+import org.dromara.product.service.IContractProductService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * author
+ * 时间:2026/1/20,13:54
+ */
+@RequiredArgsConstructor
+@Service
+@DubboService
+public class RemoteContractProductServiceImpl implements RemoteContractProdcutService {
+
+    private final IContractProductService contractProductService;
+
+
+    @Override
+    public boolean add(List<ContractProductDto> dto) {
+        boolean flag = true;
+        if (dto ==null){
+            return true;
+        }
+        List<ContractProduct> contractProducts = new ArrayList<>();
+        for (ContractProductDto bo : dto) {
+            ContractProduct contractProduct = new ContractProduct();
+            // 这里需要根据实际字段进行属性复制
+            BeanUtils.copyProperties(bo, contractProduct);
+            contractProducts.add(contractProduct);
+        }
+
+        flag = contractProductService.saveBatch(contractProducts);
+        return flag;
+    }
+
+    @Override
+    public List<ContractProductDto> queryList(Long contractSupplyId) {
+        List<ContractProduct> list = contractProductService.lambdaQuery().eq(ContractProduct::getContractSupplyId, contractSupplyId).list();
+
+        // 将实体对象转换为DTO对象
+        List<ContractProductDto> dtoList = new ArrayList<>();
+        for (ContractProduct entity : list) {
+            ContractProductDto dto = new ContractProductDto();
+            BeanUtils.copyProperties(entity, dto);
+            dtoList.add(dto);
+        }
+
+        return dtoList;
+    }
+
+    @Override
+    public boolean delete(Long contractSupplyId) {
+        List<ContractProduct> list = contractProductService.lambdaQuery()
+            .eq(ContractProduct::getContractSupplyId, contractSupplyId)
+            .select(ContractProduct::getId).list();
+        return contractProductService.removeByIds(list);
+    }
+}

+ 16 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteProductServiceImpl.java

@@ -125,6 +125,22 @@ public class RemoteProductServiceImpl implements RemoteProductService {
         return ObjectUtil.isNotEmpty(byId)?BeanUtil.toBean(byId, RemoteProductBrand.class):null;
     }
 
+    @Override
+    public List<RemoteProductBrand> getProductByBrandId(List<Long> ids) {
+        List<ProductBrand> productBrands = productBrandService.listByIds(ids);
+        if (ObjectUtil.isEmpty(productBrands)) {
+            return new ArrayList<>();
+        }
+        List<RemoteProductBrand> remoteProductBrands = productBrands.stream().map(productBrand ->
+            BeanUtil.toBean(productBrand, RemoteProductBrand.class)
+        ).collect(Collectors.toList());
+
+
+        return remoteProductBrands;
+    }
+
+
+
     @Override
     public List<ProductCategoryRemoteVo> queryList() {
         List<ProductCategoryVo> productCategoryVos = productCategoryService.queryList(new ProductCategoryBo());

+ 15 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ContractProductMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.product.mapper;
+
+import org.dromara.product.domain.ContractProduct;
+import org.dromara.product.domain.vo.ContractProductVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 合同产品关联Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface ContractProductMapper extends BaseMapperPlus<ContractProduct, ContractProductVo> {
+
+}

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

@@ -0,0 +1,70 @@
+package org.dromara.product.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.product.domain.ContractProduct;
+import org.dromara.product.domain.vo.ContractProductVo;
+import org.dromara.product.domain.bo.ContractProductBo;
+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-20
+ */
+public interface IContractProductService extends IService<ContractProduct>{
+
+    /**
+     * 查询合同产品关联
+     *
+     * @param id 主键
+     * @return 合同产品关联
+     */
+    ContractProductVo queryById(Long id);
+
+    /**
+     * 分页查询合同产品关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 合同产品关联分页列表
+     */
+    TableDataInfo<ContractProductVo> queryPageList(ContractProductBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的合同产品关联列表
+     *
+     * @param bo 查询条件
+     * @return 合同产品关联列表
+     */
+    List<ContractProductVo> queryList(ContractProductBo bo);
+
+    /**
+     * 新增合同产品关联
+     *
+     * @param bo 合同产品关联
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(ContractProductBo bo);
+
+    /**
+     * 修改合同产品关联
+     *
+     * @param bo 合同产品关联
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(ContractProductBo bo);
+
+    /**
+     * 校验并批量删除合同产品关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 140 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ContractProductServiceImpl.java

@@ -0,0 +1,140 @@
+package org.dromara.product.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.product.domain.bo.ContractProductBo;
+import org.dromara.product.domain.vo.ContractProductVo;
+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;
+
+/**
+ * 合同产品关联Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class ContractProductServiceImpl  extends ServiceImpl<ContractProductMapper, ContractProduct> implements IContractProductService {
+
+    private final ContractProductMapper baseMapper;
+
+    /**
+     * 查询合同产品关联
+     *
+     * @param id 主键
+     * @return 合同产品关联
+     */
+    @Override
+    public ContractProductVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询合同产品关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 合同产品关联分页列表
+     */
+    @Override
+    public TableDataInfo<ContractProductVo> queryPageList(ContractProductBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ContractProduct> lqw = buildQueryWrapper(bo);
+        Page<ContractProductVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的合同产品关联列表
+     *
+     * @param bo 查询条件
+     * @return 合同产品关联列表
+     */
+    @Override
+    public List<ContractProductVo> queryList(ContractProductBo bo) {
+        LambdaQueryWrapper<ContractProduct> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<ContractProduct> buildQueryWrapper(ContractProductBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<ContractProduct> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(ContractProduct::getId);
+        lqw.eq(StringUtils.isNotBlank(bo.getContractSupplyNo()), ContractProduct::getContractSupplyNo, bo.getContractSupplyNo());
+        lqw.eq(StringUtils.isNotBlank(bo.getProductNo()), ContractProduct::getProductNo, bo.getProductNo());
+        lqw.eq(bo.getProductId() != null, ContractProduct::getProductId, bo.getProductId());
+        lqw.eq(bo.getSupplyCycle() != null, ContractProduct::getSupplyCycle, bo.getSupplyCycle());
+        lqw.eq(StringUtils.isNotBlank(bo.getInventoryProperties()), ContractProduct::getInventoryProperties, bo.getInventoryProperties());
+        lqw.eq(bo.getMinSupply() != null, ContractProduct::getMinSupply, bo.getMinSupply());
+        lqw.eq(StringUtils.isNotBlank(bo.getOfferPrice()), ContractProduct::getOfferPrice, bo.getOfferPrice());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ContractProduct::getStatus, bo.getStatus());
+        return lqw;
+    }
+
+    /**
+     * 新增合同产品关联
+     *
+     * @param bo 合同产品关联
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(ContractProductBo bo) {
+        ContractProduct add = MapstructUtils.convert(bo, ContractProduct.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改合同产品关联
+     *
+     * @param bo 合同产品关联
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(ContractProductBo bo) {
+        ContractProduct update = MapstructUtils.convert(bo, ContractProduct.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(ContractProduct 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-product/src/main/resources/mapper/product/ContractProductMapper.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.product.mapper.ContractProductMapper">
+
+</mapper>

+ 112 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/AddressAreaController.java

@@ -0,0 +1,112 @@
+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.AddressAreaVo;
+import org.dromara.system.domain.bo.AddressAreaBo;
+import org.dromara.system.service.IAddressAreaService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 地区列表
+ * 前端访问路由地址为:/system/addressarea
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/addressarea")
+public class AddressAreaController extends BaseController {
+
+    private final IAddressAreaService addressAreaService;
+
+    /**
+     * 查询地区列表列表
+     */
+    @SaCheckPermission("system:addressarea:list")
+    @GetMapping("/list")
+    public TableDataInfo<AddressAreaVo> list(AddressAreaBo bo, PageQuery pageQuery) {
+        return addressAreaService.queryPageList(bo, pageQuery);
+    }
+
+
+    @GetMapping("/getChinaList")
+    public R<List<AddressAreaVo>> getChniaList(AddressAreaBo bo) {
+        return R.ok(addressAreaService.getChniaList(bo));
+    }
+
+    /**
+     * 导出地区列表列表
+     */
+    @SaCheckPermission("system:addressarea:export")
+    @Log(title = "地区列表", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(AddressAreaBo bo, HttpServletResponse response) {
+        List<AddressAreaVo> list = addressAreaService.queryList(bo);
+        ExcelUtil.exportExcel(list, "地区列表", AddressAreaVo.class, response);
+    }
+
+    /**
+     * 获取地区列表详细信息
+     *
+     * @param id 主键
+     */
+    @SaCheckPermission("system:addressarea:query")
+    @GetMapping("/{id}")
+    public R<AddressAreaVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(addressAreaService.queryById(id));
+    }
+
+    /**
+     * 新增地区列表
+     */
+    @SaCheckPermission("system:addressarea:add")
+    @Log(title = "地区列表", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody AddressAreaBo bo) {
+        return toAjax(addressAreaService.insertByBo(bo));
+    }
+
+    /**
+     * 修改地区列表
+     */
+    @SaCheckPermission("system:addressarea:edit")
+    @Log(title = "地区列表", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody AddressAreaBo bo) {
+        return toAjax(addressAreaService.updateByBo(bo));
+    }
+
+    /**
+     * 删除地区列表
+     *
+     * @param ids 主键串
+     */
+    @SaCheckPermission("system:addressarea:remove")
+    @Log(title = "地区列表", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(addressAreaService.deleteWithValidByIds(List.of(ids), true));
+    }
+}

+ 82 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/AddressArea.java

@@ -0,0 +1,82 @@
+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;
+
+/**
+ * 地区列表对象 address_area
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("address_area")
+public class AddressArea extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 地区编码
+     */
+    private String areaCode;
+
+    /**
+     * 地区名称
+     */
+    private String areaName;
+
+    /**
+     * 父类ID
+     */
+    private Long parentCode;
+
+    /**
+     * 地区简称
+     */
+    private String simpleName;
+
+    /**
+     * 地区等级省 1 市 2
+     */
+    private Long level;
+
+    /**
+     * 拼英
+     */
+    private String pinYin;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 64 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/AddressAreaBo.java

@@ -0,0 +1,64 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.AddressArea;
+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.*;
+
+/**
+ * 地区列表业务对象 address_area
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = AddressArea.class, reverseConvertGenerate = false)
+public class AddressAreaBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 地区编码
+     */
+    private String areaCode;
+
+    /**
+     * 地区名称
+     */
+    private String areaName;
+
+    /**
+     * 父类ID
+     */
+    private Long parentCode;
+
+    /**
+     * 地区简称
+     */
+    private String simpleName;
+
+    /**
+     * 地区等级省 1 市 2
+     */
+    private Long level;
+
+    /**
+     * 拼英
+     */
+    private String pinYin;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+
+}

+ 85 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/AddressAreaVo.java

@@ -0,0 +1,85 @@
+package org.dromara.system.domain.vo;
+
+import org.dromara.system.domain.AddressArea;
+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;
+import java.util.List;
+
+
+/**
+ * 地区列表视图对象 address_area
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = AddressArea.class)
+public class AddressAreaVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 地区编码
+     */
+    @ExcelProperty(value = "地区编码")
+    private String areaCode;
+
+    /**
+     * 地区名称
+     */
+    @ExcelProperty(value = "地区名称")
+    private String areaName;
+
+    /**
+     * 父类ID
+     */
+    @ExcelProperty(value = "父类ID")
+    private Long parentCode;
+
+    /**
+     * 地区简称
+     */
+    @ExcelProperty(value = "地区简称")
+    private String simpleName;
+
+    /**
+     * 地区等级省 1 市 2
+     */
+    @ExcelProperty(value = "地区等级省 1 市 2")
+    private Long level;
+
+    /**
+     * 拼英
+     */
+    @ExcelProperty(value = "拼英")
+    private String pinYin;
+
+    /**
+     * 数据来源
+     */
+    @ExcelProperty(value = "数据来源")
+    private String dataSource;
+
+    /**
+     * 树形结构
+     */
+    private List<AddressAreaVo> children;
+
+
+}

+ 1 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteSupplierTypeServiceImpl.java

@@ -30,6 +30,7 @@ public class RemoteSupplierTypeServiceImpl implements RemoteSupplierTypeService
         List<RemoteSupplierTypeVo> vos =new ArrayList<>();
         list.forEach(item -> {
             RemoteSupplierTypeVo vo = new RemoteSupplierTypeVo();
+            vo.setId(item.getId());
             vo.setTypeId(item.getSupplierTypeNo());
             vo.setTypeName(item.getSupplierTypeName());
             vos.add(vo);

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

@@ -0,0 +1,15 @@
+package org.dromara.system.mapper;
+
+import org.dromara.system.domain.AddressArea;
+import org.dromara.system.domain.vo.AddressAreaVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 地区列表Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+public interface AddressAreaMapper extends BaseMapperPlus<AddressArea, AddressAreaVo> {
+
+}

+ 72 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/IAddressAreaService.java

@@ -0,0 +1,72 @@
+package org.dromara.system.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.system.domain.AddressArea;
+import org.dromara.system.domain.vo.AddressAreaVo;
+import org.dromara.system.domain.bo.AddressAreaBo;
+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-21
+ */
+public interface IAddressAreaService extends IService<AddressArea>{
+
+    /**
+     * 查询地区列表
+     *
+     * @param id 主键
+     * @return 地区列表
+     */
+    AddressAreaVo queryById(Long id);
+
+    /**
+     * 分页查询地区列表列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 地区列表分页列表
+     */
+    TableDataInfo<AddressAreaVo> queryPageList(AddressAreaBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的地区列表列表
+     *
+     * @param bo 查询条件
+     * @return 地区列表列表
+     */
+    List<AddressAreaVo> queryList(AddressAreaBo bo);
+
+    /**
+     * 新增地区列表
+     *
+     * @param bo 地区列表
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(AddressAreaBo bo);
+
+    /**
+     * 修改地区列表
+     *
+     * @param bo 地区列表
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(AddressAreaBo bo);
+
+    /**
+     * 校验并批量删除地区列表信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    List<AddressAreaVo> getChniaList(AddressAreaBo bo);
+}

+ 209 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/AddressAreaServiceImpl.java

@@ -0,0 +1,209 @@
+package org.dromara.system.service.impl;
+
+import cn.hutool.core.collection.CollectionUtil;
+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.AddressAreaBo;
+import org.dromara.system.domain.vo.AddressAreaVo;
+import org.dromara.system.domain.AddressArea;
+import org.dromara.system.mapper.AddressAreaMapper;
+import org.dromara.system.service.IAddressAreaService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+import java.util.stream.Collectors;
+
+/**
+ * 地区列表Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-21
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class AddressAreaServiceImpl  extends ServiceImpl<AddressAreaMapper, AddressArea> implements IAddressAreaService {
+
+    private final AddressAreaMapper baseMapper;
+
+    /**
+     * 查询地区列表
+     *
+     * @param id 主键
+     * @return 地区列表
+     */
+    @Override
+    public AddressAreaVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询地区列表列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 地区列表分页列表
+     */
+    @Override
+    public TableDataInfo<AddressAreaVo> queryPageList(AddressAreaBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<AddressArea> lqw = buildQueryWrapper(bo);
+        Page<AddressAreaVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的地区列表列表
+     *
+     * @param bo 查询条件
+     * @return 地区列表列表
+     */
+    @Override
+    public List<AddressAreaVo> queryList(AddressAreaBo bo) {
+        LambdaQueryWrapper<AddressArea> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<AddressArea> buildQueryWrapper(AddressAreaBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<AddressArea> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(AddressArea::getId);
+        return lqw;
+    }
+
+    /**
+     * 新增地区列表
+     *
+     * @param bo 地区列表
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(AddressAreaBo bo) {
+        AddressArea add = MapstructUtils.convert(bo, AddressArea.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改地区列表
+     *
+     * @param bo 地区列表
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(AddressAreaBo bo) {
+        AddressArea update = MapstructUtils.convert(bo, AddressArea.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(AddressArea 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<AddressAreaVo> getChniaList(AddressAreaBo bo) {
+        // 1. 第一步:查询"中国"(level=0)的地区编码(核心父节点)
+        LambdaQueryWrapper<AddressArea> chinaWrapper = new LambdaQueryWrapper<AddressArea>()
+            .eq(AddressArea::getLevel, 0)  // level=0 代表国家级别
+            .eq(AddressArea::getAreaName, "中国");  // 匹配中国名称(根据数据库实际值调整)
+        AddressArea chinaArea = baseMapper.selectOne(chinaWrapper);
+        if (chinaArea == null) {
+            return List.of();
+        }
+        // 2. 第二步:查询中国下的所有省(level=1,parentCode=中国编码)
+        LambdaQueryWrapper<AddressArea> provinceWrapper = new LambdaQueryWrapper<AddressArea>()
+            .eq(AddressArea::getParentCode, chinaArea.getId())  // 父编码=中国编码
+            .eq(AddressArea::getLevel, 1)  // 只查省(level=1)
+            .orderByAsc(AddressArea::getAreaCode); // 按编码排序
+        List<AddressAreaVo> provinceList = baseMapper.selectVoList(provinceWrapper);
+        if (CollectionUtil.isEmpty(provinceList)) {
+            return List.of(); // 无省份数据,返回空
+        }
+        List<Long> provinceCodeList = provinceList.stream()
+            .map(AddressAreaVo::getId)
+            .collect(Collectors.toList());
+
+        // 4. 第四步:查询所有市(level=2,parentCode属于省的areaCode列表)
+        LambdaQueryWrapper<AddressArea> cityWrapper = new LambdaQueryWrapper<AddressArea>()
+            .in(AddressArea::getParentCode, provinceCodeList)  // 父编码=任意省的编码
+            .eq(AddressArea::getLevel, 2)  // 只查市(level=2)
+            .orderByAsc(AddressArea::getAreaCode);
+        List<AddressAreaVo> cityList = baseMapper.selectVoList(cityWrapper);
+
+        // 5. 第五步:将省和市转换为Vo,并构建树形结构
+        // 5.2 市Entity转Vo,并按父编码(省编码)分组
+        Map<Long, List<AddressAreaVo>> cityVoMap = cityList.stream()
+            .collect(Collectors.groupingBy(AddressAreaVo::getParentCode));
+
+        // 5.3 为每个省挂载对应的市
+        provinceList.forEach(provinceVo -> {
+            // 根据省的areaCode找对应的市列表
+            List<AddressAreaVo> childCities = cityVoMap.get(provinceVo.getId());
+            provinceVo.setChildren(childCities); // 市作为省的子节点
+        });
+
+
+
+        return provinceList;
+    }
+
+
+    /**
+     * 私有方法:构建省-市树形结构
+     */
+    private void buildAreaTree(List<AddressAreaVo> areaVoList) {
+        if (CollectionUtil.isEmpty(areaVoList)) {
+            return;
+        }
+
+        // 1. 拆分省(level=1)和市(level=2)
+        List<AddressAreaVo> provinceList = areaVoList.stream()
+            .filter(vo -> 1 == vo.getLevel())
+            .collect(Collectors.toList());
+        List<AddressAreaVo> cityList = areaVoList.stream()
+            .filter(vo -> 2 == vo.getLevel())
+            .collect(Collectors.toList());
+
+        // 2. 按市的父编码(省编码)分组
+        Map<String, List<AddressAreaVo>> cityGroupByProvinceCode = cityList.stream()
+            .collect(Collectors.groupingBy(vo -> vo.getParentCode().toString())); // 注意类型转换
+
+        // 3. 为每个省挂载对应的市
+        provinceList.forEach(province -> {
+            List<AddressAreaVo> childrenCities = cityGroupByProvinceCode.get(province.getId());
+            province.setChildren(childrenCities); // 市列表作为省的children
+        });
+    }
+}

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/resources/mapper/system/AddressAreaMapper.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.AddressAreaMapper">
+
+</mapper>

+ 1 - 1
ruoyi-visual/ruoyi-nacos/src/main/resources/application.properties

@@ -40,7 +40,7 @@ spring.sql.init.platform=mysql
 db.num=1
 
 ### Connect URL of DB:
-db.url.0=jdbc:mysql://192.168.1.123:3306/yoe_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
+db.url.0=jdbc:mysql://yp1.yingpaipay.com:9031/yoe_config?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true&useUnicode=true&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true
 db.user.0=youyida
 db.password.0=aapYBDthby
 

Некоторые файлы не были показаны из-за большого количества измененных файлов