Explorar o código

feat(docker): 新增商品管理模块及外部系统对接功能

- 添加 ruoyi-product、ruoyi-external、ruoyi-order、ruoyi-customer 四个微服务容器配置
- 创建商品管理模块 Dockerfile 配置文件
- 修复商品 jar 包文件名拼写错误
- 添加第三方商品对接相关实体类和接口定义
- 实现商品上下架、批量推送、分类树查询等功能
- 集成 SkyWalking 探针监控配置
- 添加 Docker 容器时区设置为上海
- 实现外部商品与内部商品数据同步逻辑
- 新增 Dubbo 远程调用接口用于商品对接状态查询
- 优化部门管理服务中的客户ID查询条件
- 添加商品分类审核人员设置功能
肖路 hai 2 meses
pai
achega
1f0f0c3a4a
Modificáronse 27 ficheiros con 868 adicións e 22 borrados
  1. 13 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/service/RemoteExternalProductService.java
  2. 27 0
      ruoyi-modules/ruoyi-customer/Dockerfile
  3. 18 0
      ruoyi-modules/ruoyi-external/pom.xml
  4. 9 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/ExternalProductCategoryController.java
  5. 28 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/ExternalProductController.java
  6. 23 2
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalProduct.java
  7. 25 8
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalProductBo.java
  8. 342 2
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductVo.java
  9. 52 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteExternalProductServiceImpl.java
  10. 17 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/IExternalProductCategoryService.java
  11. 25 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/IExternalProductService.java
  12. 37 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalProductCategoryServiceImpl.java
  13. 59 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalProductServiceImpl.java
  14. 27 0
      ruoyi-modules/ruoyi-order/Dockerfile
  15. 1 1
      ruoyi-modules/ruoyi-product/Dockerfile
  16. 18 0
      ruoyi-modules/ruoyi-product/pom.xml
  17. 2 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBaseController.java
  18. 18 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductCategoryController.java
  19. 6 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ProductCategory.java
  20. 4 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductCategoryBo.java
  21. 5 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductCategoryVo.java
  22. 15 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductCategoryService.java
  23. 1 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
  24. 27 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java
  25. 1 1
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductCategoryRecommendedMapper.xml
  26. 7 5
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java
  27. 61 0
      script/docker/docker-compose.yml

+ 13 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/service/RemoteExternalProductService.java

@@ -0,0 +1,13 @@
+package org.dromara.external.api.service;
+
+/**
+ * @author
+ * @date 2026/1/14 下午4:58
+ */
+public interface RemoteExternalProductService {
+
+    /**
+    * 获取商品的对接状态
+    * */
+    Boolean getProductDockingStatus(Long productId,String itemKey);
+}

+ 27 - 0
ruoyi-modules/ruoyi-customer/Dockerfile

@@ -0,0 +1,27 @@
+# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
+FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds
+#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds
+#FROM findepi/graalvm:java17-native
+
+LABEL maintainer="Lion Li"
+
+RUN mkdir -p /ruoyi/customer/logs \
+    /ruoyi/customer/temp \
+    /ruoyi/skywalking/agent
+
+WORKDIR /ruoyi/customer
+
+ENV SERVER_PORT=9212 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
+
+EXPOSE ${SERVER_PORT}
+
+ADD ./target/ruoyi-customer.jar ./app.jar
+
+SHELL ["/bin/bash", "-c"]
+
+ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
+           #-Dskywalking.agent.service_name=ruoyi-customer \
+           #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
+           -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
+           -jar app.jar
+

+ 18 - 0
ruoyi-modules/ruoyi-external/pom.xml

@@ -125,5 +125,23 @@
         </dependency>
     </dependencies>
 
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
 
 </project>

+ 9 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/ExternalProductCategoryController.java

@@ -2,6 +2,7 @@ package org.dromara.external.controller;
 
 import java.util.List;
 
+import cn.hutool.core.lang.tree.Tree;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
@@ -103,4 +104,12 @@ public class ExternalProductCategoryController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(externalProductCategoryService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+     * 获取分类树列表
+     */
+    @GetMapping("/categoryTree")
+    public R<List<Tree<Long>>> categoryTree(ExternalProductCategoryBo  bo) {
+        return R.ok(externalProductCategoryService.selectCategoryTreeList(bo));
+    }
 }

+ 28 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/ExternalProductController.java

@@ -103,4 +103,32 @@ public class ExternalProductController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(externalProductService.deleteWithValidByIds(List.of(ids), true));
     }
+
+
+    /**
+     * 获取第三方商品列表
+     * */
+    @GetMapping("/getThirdProductPage")
+    public TableDataInfo<ExternalProductVo> getThirdProductPage(ExternalProductBo bo, PageQuery pageQuery) {
+        return externalProductService.getThirdProductPage(bo, pageQuery);
+    }
+
+    /**
+    * 批量推送商品
+    * */
+    @PostMapping("/batchPush/{ids}")
+    public R<Void> batchPush(@NotEmpty(message = "主键不能为空")
+                             @PathVariable("ids") Long[] ids) {
+        return toAjax(externalProductService.batchPush(ids));
+    }
+
+    /**
+    * 商品上下架
+    * */
+    @PostMapping("/shelfReview")
+    public R<Void> shelfReview(@Validated @RequestBody ExternalProductBo bo) {
+        return toAjax(externalProductService.shelfReview(bo));
+    }
+
+
 }

+ 23 - 2
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalProduct.java

@@ -1,5 +1,6 @@
 package org.dromara.external.domain;
 
+import java.math.BigDecimal;
 import org.dromara.common.tenant.core.TenantEntity;
 import com.baomidou.mybatisplus.annotation.*;
 import lombok.Data;
@@ -22,7 +23,7 @@ public class ExternalProduct extends TenantEntity {
     private static final long serialVersionUID = 1L;
 
     /**
-     * 
+     *
      */
     @TableId(value = "id")
     private Long id;
@@ -32,6 +33,16 @@ public class ExternalProduct extends TenantEntity {
      */
     private Long productId;
 
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
     /**
      * 项目id
      */
@@ -45,7 +56,7 @@ public class ExternalProduct extends TenantEntity {
     /**
      * 外部分类id
      */
-    private Long externlCategoryId;
+    private Long externalCategoryId;
 
     /**
      * 推送状态 0未推送,1已推送
@@ -63,5 +74,15 @@ public class ExternalProduct extends TenantEntity {
      */
     private String remark;
 
+    /**
+     *  第三方价格
+     * */
+    private BigDecimal externalPrice;
+
+    /**
+     * 商品状态:1=已上架,0=下架
+     * */
+    private Integer productStatus;
+
 
 }

+ 25 - 8
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalProductBo.java

@@ -1,5 +1,6 @@
 package org.dromara.external.domain.bo;
 
+import java.math.BigDecimal;
 import org.dromara.external.domain.ExternalProduct;
 import org.dromara.common.mybatis.core.domain.BaseEntity;
 import org.dromara.common.core.validate.AddGroup;
@@ -21,45 +22,61 @@ import jakarta.validation.constraints.*;
 public class ExternalProductBo extends BaseEntity {
 
     /**
-     * 
+     *
      */
     private Long id;
 
     /**
      * 商品id
      */
-    @NotNull(message = "商品id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long productId;
 
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
     /**
      * 项目id
      */
-    @NotNull(message = "项目id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long itemId;
 
     /**
      * 分类id
      */
-    @NotNull(message = "分类id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long categoryId;
 
     /**
      * 外部分类id
      */
-    @NotNull(message = "外部分类id不能为空", groups = { AddGroup.class, EditGroup.class })
-    private Long externlCategoryId;
+    private Long externalCategoryId;
 
     /**
      * 推送状态 0未推送,1已推送
      */
-    @NotNull(message = "推送状态 0未推送,1已推送不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long pushStatus;
 
     /**
      * 备注
      */
-    @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
     private String remark;
 
+    /**
+    *  第三方价格
+    * */
+    private BigDecimal externalPrice;
+
+    /**
+    * 商品状态:1=已上架,0=下架
+    * */
+    private Integer productStatus;
+
+
+
 
 }

+ 342 - 2
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductVo.java

@@ -10,6 +10,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -29,7 +30,7 @@ public class ExternalProductVo implements Serializable {
     private static final long serialVersionUID = 1L;
 
     /**
-     * 
+     *
      */
     @ExcelProperty(value = "")
     private Long id;
@@ -56,7 +57,7 @@ public class ExternalProductVo implements Serializable {
      * 外部分类id
      */
     @ExcelProperty(value = "外部分类id")
-    private Long externlCategoryId;
+    private Long externalCategoryId;
 
     /**
      * 推送状态 0未推送,1已推送
@@ -70,5 +71,344 @@ public class ExternalProductVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+     *  第三方价格
+     * */
+    private BigDecimal externalPrice;
+
+    /**
+     * 产品编号
+     */
+    private String productNo;
+
+    /**
+     * 产品名称
+     */
+    private String itemName;
+
+    /**
+     * 品牌id
+     */
+    private Long brandId;
+
+    /**
+     * 品牌名称
+     */
+    private String brandName;
+
+    /**
+     * 顶级分类id
+     */
+    private Long topCategoryId;
+
+    /**
+     * 中级分类id
+     */
+    private Long mediumCategoryId;
+
+    /**
+     * 底层分类id
+     */
+    private Long bottomCategoryId;
+
+    /**
+     * 分类名称
+     * */
+    private String categoryName;
+
+    /**
+     * 单位id
+     */
+    private String unitId;
+
+    /**
+     * 单位名称
+     * */
+    private String unitName;
+
+    /**
+     * 产品图片URL
+     */
+    private String productImage;
+
+    /**
+     * 产品图片URLUrl
+     */
+    private String productImageUrl;
+    /**
+     * 是否自营(1=是,0=否)
+     */
+    private Integer isSelf;
+
+    /**
+     * 产品审核状态 0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+
+    private Integer productReviewStatus;
+
+    /**
+     * 首页推荐:1=推荐,0=不推荐
+     */
+    private Integer homeRecommended;
+
+    /**
+     * 分类推荐:1=推荐,0=不推荐
+     */
+    private Integer categoryRecommendation;
+
+    /**
+     * 购物车推荐:1=推荐,0=不推荐
+     */
+    private Integer cartRecommendation;
+
+    /**
+     * 推荐产品顺序
+     */
+    private Long recommendedProductOrder;
+
+    /**
+     * 是否热门:1=是,0=否
+     */
+    private Integer isPopular;
+
+    /**
+     * 是否新品:1=是,0=否
+     */
+    private Integer isNew;
+
+    /**
+     * 商品状态:1=已上架,0=下架 2 上架中等
+     */
+    Integer productStatus;
+
+    /**
+     * 数据来源
+     */
+    private String dataSource;
+
+    /**
+     * 市场价
+     * */
+    private java.math.BigDecimal marketPrice;
+
+    /**
+     * 会员价格
+     */
+    private java.math.BigDecimal memberPrice;
+
+    /**
+     * 最低销售价格
+     */
+    private java.math.BigDecimal minSellingPrice;
+
+    /**
+     * 采购价格
+     */
+    private java.math.BigDecimal purchasingPrice;
+
+
+
+    /**
+     * 暂估毛利率
+     * */
+    private java.math.BigDecimal tempGrossMargin;
+
+    /**
+     * 总库存
+     * */
+    private Long totalInventory;
+
+    /**
+     * A10产品名称
+     */
+    private String a10ProductName;
+
+    /**
+     * 规格型号
+     */
+    private String specification;
+
+    /**
+     * UPC(S)条码
+     */
+    private String upcBarcode;
+
+    /**
+     * 发票名称
+     */
+    private String invoiceName;
+
+    /**
+     * 发票规格
+     */
+    private String invoiceSpec;
+
+    /**
+     * 包装规格
+     */
+    private String packagingSpec;
+
+    /**
+     * 参考链接
+     */
+    private String referenceLink;
+
+    /**
+     * 商品重量
+     */
+    private String weight;
+
+    /**
+     * 重量单位
+     */
+    private String weightUnit;
+
+    /**
+     * 商品体积
+     */
+    private String volume;
+
+    /**
+     * 体积单位
+     */
+    private String volumeUnit;
+
+    /**
+     * 主库简介
+     */
+    private String mainLibraryIntro;
+
+    /**
+     * 售后服务
+     */
+    private String afterSalesService;
+
+    /**
+     * 服务保证 - 无忧退货
+     */
+    private String worryFreeReturn;
+
+    /**
+     * 服务保证 - 快速退款
+     */
+    private String quickRefund;
+
+    /**
+     * 服务保证 - 免费包邮
+     */
+    private String freeShipping;
+
+    /**
+     * 服务保证 - 正品保障
+     */
+    private String genuineGuarantee;
+
+    /**
+     * 安装服务 - 免费安装
+     */
+    private String freeInstallation;
+
+    /**
+     * 中档价
+     */
+    private java.math.BigDecimal midRangePrice;
+
+    /**
+     * 平档价
+     */
+
+    private java.math.BigDecimal standardPrice;
+
+    /**
+     * 套证价
+     */
+    private java.math.BigDecimal certificatePrice;
+
+    /**
+     * 采购价
+     */
+    private java.math.BigDecimal purchasePrice;
+
+    /**
+     * 暂估采购价
+     */
+    private java.math.BigDecimal estimatedPurchasePrice;
+
+    /**
+     * 产品性质
+     */
+    private String productNature;
+
+    /**
+     * 采购人员
+     */
+    private String purchasingPersonnel;
+
+    /**
+     * 商品详情 - 电脑端
+     */
+    private String pcDetail;
+
+    /**
+     * 商品详情 - 移动端
+     */
+    private String mobileDetail;
+
+    /**
+     * 税率
+     */
+    private java.math.BigDecimal taxRate;
+
+    /**
+     * 币种
+     */
+    private String currency;
+
+    /**
+     * 最低起订量
+     */
+    private Long minOrderQuantity;
+
+    /**
+     * 是否可定制
+     */
+    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;
+
+
 
 }

+ 52 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteExternalProductServiceImpl.java

@@ -0,0 +1,52 @@
+package org.dromara.external.dubbo;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.external.api.service.RemoteExternalProductService;
+import org.dromara.external.domain.ExternalItem;
+import org.dromara.external.domain.ExternalProduct;
+import org.dromara.external.service.IExternalItemService;
+import org.dromara.external.service.IExternalProductService;
+import org.springframework.stereotype.Service;
+
+/**
+ * @author
+ * @date 2026/1/14 下午5:02
+ */
+@Slf4j
+@Service
+@RequiredArgsConstructor
+@DubboService
+public class RemoteExternalProductServiceImpl implements RemoteExternalProductService {
+
+    private final IExternalProductService externalProductService;
+
+    private final IExternalItemService externalItemService;
+
+    /**
+     * 获取商品的对接状态
+     *
+     * @param productId
+     * @param itemKey
+     */
+    @Override
+    public Boolean getProductDockingStatus(Long productId, String itemKey) {
+        //获取项目id
+        ExternalItem one = externalItemService.getOne(Wrappers.lambdaQuery(ExternalItem.class)
+            .eq(ExternalItem::getItemKey, itemKey)
+            .eq(ExternalItem::getStatus, "1")
+            .last("limit 1")
+        );
+        if (ObjectUtil.isEmpty(one)) {
+            return false;
+        }
+        ExternalProduct externalProduct = externalProductService.getOne(Wrappers.lambdaQuery(ExternalProduct.class)
+            .eq(ExternalProduct::getProductId, productId)
+            .eq(ExternalProduct::getItemId, one.getId())
+        );
+        return ObjectUtil.isNotEmpty(externalProduct);
+    }
+}

+ 17 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/IExternalProductCategoryService.java

@@ -1,5 +1,6 @@
 package org.dromara.external.service;
 
+import cn.hutool.core.lang.tree.Tree;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.external.domain.ExternalProductCategory;
 import org.dromara.external.domain.vo.ExternalProductCategoryVo;
@@ -67,4 +68,20 @@ public interface IExternalProductCategoryService extends IService<ExternalProduc
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 构建前端所需要下拉树结构
+     *
+     * @param productCategorys 产品分类列表
+     * @return 下拉树结构列表
+     */
+    List<Tree<Long>> buildTreeSelect(List<ExternalProductCategoryVo> productCategorys);
+
+    /**
+     * 查询产品分类列表
+     *
+     * @param bo 查询条件
+     * @return 产品分类列表
+     */
+    List<Tree<Long>> selectCategoryTreeList(ExternalProductCategoryBo bo);
 }

+ 25 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/IExternalProductService.java

@@ -67,4 +67,29 @@ public interface IExternalProductService extends IService<ExternalProduct>{
      * @return 是否删除成功
      */
     Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 获取第三方商品列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 第三方商品列表
+     */
+    TableDataInfo<ExternalProductVo> getThirdProductPage(ExternalProductBo bo, PageQuery pageQuery);
+
+    /**
+     * 批量推送商品
+     *
+     * @param ids 商品id
+     * @return 推送成功数量
+     */
+    int batchPush(Long[] ids);
+
+    /**
+     * 商品上下架
+     *
+     * @param bo 商品审核参数
+     * @return 是否审核成功
+     */
+    Boolean shelfReview(ExternalProductBo bo);
 }

+ 37 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalProductCategoryServiceImpl.java

@@ -1,8 +1,11 @@
 package org.dromara.external.service.impl;
 
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.lang.tree.Tree;
 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.core.utils.TreeBuildUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
 import org.dromara.common.mybatis.core.page.PageQuery;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
@@ -141,4 +144,38 @@ public class ExternalProductCategoryServiceImpl  extends ServiceImpl<ExternalPro
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    /**
+     * 构建前端所需要下拉树结构
+     *
+     * @param productCategorys 产品分类列表
+     * @return 下拉树结构列表
+     */
+    @Override
+    public List<Tree<Long>> buildTreeSelect(List<ExternalProductCategoryVo> productCategorys) {
+        if (CollUtil.isEmpty(productCategorys)) {
+            return CollUtil.newArrayList();
+        }
+        return TreeBuildUtils.buildMultiRoot(
+            productCategorys,
+            ExternalProductCategoryVo::getId,
+            ExternalProductCategoryVo::getParentId,
+            (node, treeNode) -> treeNode
+                .setId(node.getId())
+                .setParentId(node.getParentId())
+                .setName(node.getCategoryName())
+        );
+    }
+
+    /**
+     * 查询产品分类列表
+     *
+     * @param bo 查询条件
+     * @return 产品分类列表
+     */
+    @Override
+    public List<Tree<Long>> selectCategoryTreeList(ExternalProductCategoryBo bo) {
+        List<ExternalProductCategoryVo> list = queryList(bo);
+        return buildTreeSelect(list);
+    }
 }

+ 59 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalProductServiceImpl.java

@@ -1,6 +1,9 @@
 package org.dromara.external.service.impl;
 
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.common.mybatis.core.page.TableDataInfo;
@@ -10,6 +13,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.product.api.RemoteProductService;
+import org.dromara.product.api.domain.ProductVo;
 import org.springframework.stereotype.Service;
 import org.dromara.external.domain.bo.ExternalProductBo;
 import org.dromara.external.domain.vo.ExternalProductVo;
@@ -34,6 +39,9 @@ public class ExternalProductServiceImpl  extends ServiceImpl<ExternalProductMapp
 
     private final ExternalProductMapper baseMapper;
 
+    @DubboReference
+    private RemoteProductService remoteProductService;
+
     /**
      * 查询对外部推送商品
      *
@@ -78,7 +86,6 @@ public class ExternalProductServiceImpl  extends ServiceImpl<ExternalProductMapp
         lqw.eq(bo.getProductId() != null, ExternalProduct::getProductId, bo.getProductId());
         lqw.eq(bo.getItemId() != null, ExternalProduct::getItemId, bo.getItemId());
         lqw.eq(bo.getCategoryId() != null, ExternalProduct::getCategoryId, bo.getCategoryId());
-        lqw.eq(bo.getExternlCategoryId() != null, ExternalProduct::getExternlCategoryId, bo.getExternlCategoryId());
         lqw.eq(bo.getPushStatus() != null, ExternalProduct::getPushStatus, bo.getPushStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ExternalProduct::getPlatformCode, bo.getPlatformCode());
         return lqw;
@@ -135,4 +142,55 @@ public class ExternalProductServiceImpl  extends ServiceImpl<ExternalProductMapp
         }
         return baseMapper.deleteByIds(ids) > 0;
     }
+
+    /**
+     * 获取第三方商品列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 第三方商品列表
+     */
+    @Override
+    public TableDataInfo<ExternalProductVo> getThirdProductPage(ExternalProductBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<ExternalProduct> lambdaQueryWrapper = buildQueryWrapper(bo);
+        Page<ExternalProductVo> result = baseMapper.selectVoPage(pageQuery.build(),lambdaQueryWrapper );
+        result.getRecords().forEach(item -> {
+            ExternalProductVo externalProductVo = BeanUtil.toBean(item, ExternalProductVo.class);
+            ProductVo productDetail = remoteProductService.getProductDetail(item.getProductId());
+            BeanUtil.copyProperties(productDetail, item);
+            item.setId(externalProductVo.getId());
+            item.setProductStatus(externalProductVo.getProductStatus());
+        });
+        return TableDataInfo.build( result);
+    }
+
+    /**
+     * 批量推送商品
+     *
+     * @param ids 商品id
+     * @return 推送成功数量
+     */
+    @Override
+    public int batchPush(Long[] ids) {
+        List<ExternalProduct> externalProducts = baseMapper.selectList(new LambdaQueryWrapper<ExternalProduct>().eq(ExternalProduct::getPushStatus, 0).in(ExternalProduct::getId, ids));
+        if (CollUtil.isNotEmpty(externalProducts)) {
+        }
+        return baseMapper.update(Wrappers.lambdaUpdate(ExternalProduct.class)
+            .set(ExternalProduct::getPushStatus, 1)
+            .in(ExternalProduct::getId, ids));
+    }
+
+
+    /**
+     * 商品上下架
+     *
+     * @param bo
+     */
+    @Override
+    public Boolean shelfReview(ExternalProductBo bo) {
+       return baseMapper.update(Wrappers.lambdaUpdate(ExternalProduct.class)
+            .set(ExternalProduct::getProductStatus, bo.getProductStatus())
+            .eq(ExternalProduct::getId, bo.getId())
+        )>0;
+    }
 }

+ 27 - 0
ruoyi-modules/ruoyi-order/Dockerfile

@@ -0,0 +1,27 @@
+# 贝尔实验室 Spring 官方推荐镜像 JDK下载地址 https://bell-sw.com/pages/downloads/
+FROM bellsoft/liberica-openjdk-rocky:17.0.15-cds
+#FROM bellsoft/liberica-openjdk-rocky:21.0.7-cds
+#FROM findepi/graalvm:java17-native
+
+LABEL maintainer="Lion Li"
+
+RUN mkdir -p /ruoyi/order/logs \
+    /ruoyi/order/temp \
+    /ruoyi/skywalking/agent
+
+WORKDIR /ruoyi/order
+
+ENV SERVER_PORT=9213 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
+
+EXPOSE ${SERVER_PORT}
+
+ADD ./target/ruoyi-order.jar ./app.jar
+
+SHELL ["/bin/bash", "-c"]
+
+ENTRYPOINT java -Djava.security.egd=file:/dev/./urandom -Dserver.port=${SERVER_PORT} \
+           #-Dskywalking.agent.service_name=ruoyi-order \
+           #-javaagent:/ruoyi/skywalking/agent/skywalking-agent.jar \
+           -XX:+HeapDumpOnOutOfMemoryError -XX:+UseZGC ${JAVA_OPTS} \
+           -jar app.jar
+

+ 1 - 1
ruoyi-modules/ruoyi-product/Dockerfile

@@ -15,7 +15,7 @@ ENV SERVER_PORT=9608 LANG=C.UTF-8 LC_ALL=C.UTF-8 JAVA_OPTS=""
 
 EXPOSE ${SERVER_PORT}
 
-ADD ./target/ruoyi-prouct.jar ./app.jar
+ADD ./target/ruoyi-product.jar ./app.jar
 
 SHELL ["/bin/bash", "-c"]
 

+ 18 - 0
ruoyi-modules/ruoyi-product/pom.xml

@@ -117,4 +117,22 @@
 
     </dependencies>
 
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
 </project>

+ 2 - 1
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBaseController.java

@@ -207,11 +207,12 @@ public class ProductBaseController extends BaseController {
     }
 
     /**
-    * 商品上下架 状态变更
+//    * 商品上下架 状态变更
     * */
     @PostMapping("/shelfReview")
     public R<Void> shelfReview(@Validated @RequestBody ProductBaseBo bo) {
         productBaseService.shelfReview(bo);
         return R.ok();
     }
+
 }

+ 18 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductCategoryController.java

@@ -2,6 +2,7 @@ package org.dromara.product.controller;
 
 import java.util.List;
 
+import cn.hutool.core.lang.tree.Tree;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
@@ -103,4 +104,21 @@ public class ProductCategoryController extends BaseController {
                           @PathVariable("ids") Long[] ids) {
         return toAjax(productCategoryService.deleteWithValidByIds(List.of(ids), true));
     }
+
+    /**
+    * 设置审核人员
+    * */
+    @Log(title = "产品分类", businessType = BusinessType.UPDATE)
+    @PutMapping("/setReviewer")
+    public R<Void> setReviewer(@RequestBody ProductCategoryBo bo) {
+        return toAjax(productCategoryService.setReviewer(bo));
+    }
+
+    /**
+    * 查询产品分类树(排除节点)
+    * */
+    @GetMapping("/tree/exclude/{excludeIds}")
+    public R<List<Tree<Long>>> listExclude(@PathVariable("excludeIds") String excludeIds) {
+        return R.ok(productCategoryService.queryPageListExclude(excludeIds));
+    }
 }

+ 6 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ProductCategory.java

@@ -150,4 +150,10 @@ public class ProductCategory extends TenantEntity {
     private String remark;
 
 
+    /**
+     * 审核人
+     */
+    private Long reviewerId;
+
+
 }

+ 4 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductCategoryBo.java

@@ -162,5 +162,9 @@ public class ProductCategoryBo extends BaseEntity {
     //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
     private String remark;
 
+    /**
+     * 审核人
+     */
+    private Long reviewerId;
 
 }

+ 5 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductCategoryVo.java

@@ -179,5 +179,10 @@ public class ProductCategoryVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+     * 审核人
+     */
+    private Long reviewerId;
+
 
 }

+ 15 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductCategoryService.java

@@ -84,5 +84,20 @@ public interface IProductCategoryService extends IService<ProductCategory>{
     List<Tree<Long>> buildTreeSelect(List<ProductCategoryVo> productCategorys);
 
 
+    /**
+     * 设置审核人员
+     *
+     * @param bo
+     * @return
+     */
+    Boolean setReviewer(ProductCategoryBo bo);
+
 
+    /**
+     * 查询产品分类列表(排除节点)
+     *
+     * @param excludeIds 排除节点
+     * @return 产品分类列表
+     */
+    List<Tree<Long>> queryPageListExclude(String excludeIds);
 }

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

@@ -1024,7 +1024,7 @@ public class ProductBaseServiceImpl  extends ServiceImpl<ProductBaseMapper, Prod
     @Override
     public void shelfReview(ProductBaseBo bo) {
         baseMapper.update(Wrappers.lambdaUpdate(ProductBase.class)
-            .set(ProductBase::getIsSelf, bo.getIsSelf())
+            .set(ProductBase::getProductStatus, bo.getProductStatus())
             .eq(ProductBase::getId, bo.getId())
         );
         extendMapper.update(Wrappers.lambdaUpdate(ProductExtend.class)

+ 27 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java

@@ -194,4 +194,31 @@ public class ProductCategoryServiceImpl  extends ServiceImpl<ProductCategoryMapp
                 .putExtra("isShow", node.getIsShow())
         );
     }
+
+    /**
+     * 设置审核人员
+     *
+     * @param bo
+     * @return
+     */
+    @Override
+    public Boolean setReviewer(ProductCategoryBo bo) {
+        return baseMapper.update(Wrappers.lambdaUpdate(ProductCategory.class)
+            .eq(ProductCategory::getId, bo.getId())
+            .set(ProductCategory::getReviewerId, bo.getReviewerId())
+        ) > 0;
+    }
+
+    /**
+     * 查询产品分类树(排除节点)
+     *
+     * @param excludeIds 排除节点
+     * @return 产品分类列表
+     */
+    @Override
+    public List<Tree<Long>> queryPageListExclude(String excludeIds) {
+        LambdaQueryWrapper<ProductCategory> lqw = new LambdaQueryWrapper<>();
+        lqw.ne(StringUtils.isNotBlank(excludeIds), ProductCategory::getId, excludeIds);
+        return buildTreeSelect(baseMapper.selectVoList(lqw));
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductCategoryRecommendedMapper.xml

@@ -2,6 +2,6 @@
 <!DOCTYPE mapper
 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-<mapper namespace="org.dromara.system.mapper.ProductCategoryRecommendedMapper">
+<mapper namespace="org.dromara.product.mapper.ProductCategoryRecommendedMapper">
 
 </mapper>

+ 7 - 5
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/service/impl/SysDeptServiceImpl.java

@@ -37,10 +37,7 @@ import org.springframework.cache.annotation.Caching;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
 
 /**
  * 部门管理 服务实现
@@ -68,6 +65,7 @@ public class SysDeptServiceImpl implements ISysDeptService {
         return TableDataInfo.build(page);
     }
 
+
     /**
      * 查询部门管理数据
      *
@@ -99,7 +97,7 @@ public class SysDeptServiceImpl implements ISysDeptService {
         lqw.eq(SysDept::getDelFlag, SystemConstants.NORMAL);
         lqw.eq(ObjectUtil.isNotNull(bo.getDeptId()), SysDept::getDeptId, bo.getDeptId());
         lqw.eq(ObjectUtil.isNotNull(bo.getParentId()), SysDept::getParentId, bo.getParentId());
-        lqw.eq(ObjectUtil.isNotNull(bo.getCustomerId()), SysDept::getCustomerId, bo.getCustomerId());
+//        lqw.eq(ObjectUtil.isNotNull(bo.getCustomerId()), SysDept::getCustomerId, bo.getCustomerId());
         lqw.like(StringUtils.isNotBlank(bo.getDeptName()), SysDept::getDeptName, bo.getDeptName());
         lqw.like(StringUtils.isNotBlank(bo.getDeptCategory()), SysDept::getDeptCategory, bo.getDeptCategory());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), SysDept::getStatus, bo.getStatus());
@@ -426,4 +424,8 @@ public class SysDeptServiceImpl implements ISysDeptService {
             .eq(SysDept::getStatus, SystemConstants.NORMAL));
     }
 
+    @Override
+    public Map<Long, String> selectDeptNameByIds(Set<Long> ids) {
+        return Map.of();
+    }
 }

+ 61 - 0
script/docker/docker-compose.yml

@@ -226,6 +226,67 @@ services:
     privileged: true
     network_mode: "host"
 
+  ruoyi-product:
+    image: ruoyi/ruoyi-product:2.4.1
+    container_name: ruoyi-product
+    environment:
+      # 时区上海
+      TZ: Asia/Shanghai
+    ports:
+      - "9608:9608"
+    volumes:
+      # 配置文件
+      - /home/docker/ruoyi-product/logs/:/ruoyi/product/logs
+      # skywalking 探针
+      - /home/docker/skywalking/agent/:/ruoyi/skywalking/agent
+    privileged: true
+    network_mode: "host"
+
+  ruoyi-external:
+    image: ruoyi/ruoyi-external:2.4.1
+    container_name: ruoyi-external
+    environment:
+      # 时区上海
+      TZ: Asia/Shanghai
+    ports:
+      - "9618:9618"
+    volumes:
+      # 配置文件
+      - /home/docker/ruoyi-external/logs/:/ruoyi/external/logs
+      # skywalking 探针
+      - /home/docker/skywalking/agent/:/ruoyi/skywalking/agent
+    privileged: true
+    network_mode: "host"
+  ruoyi-order:
+    image: ruoyi/ruoyi-order:2.4.1
+    container_name: ruoyi-order
+    environment:
+      # 时区上海
+      TZ: Asia/Shanghai
+    ports:
+      - "9213:9213"
+    volumes:
+      # 配置文件
+      - /home/docker/ruoyi-external/logs/:/ruoyi/order/logs
+      # skywalking 探针
+      - /home/docker/skywalking/agent/:/ruoyi/skywalking/agent
+    privileged: true
+    network_mode: "host"
+  ruoyi-customer:
+    image: ruoyi/ruoyi-customer:2.4.1
+    container_name: ruoyi-customer
+    environment:
+      # 时区上海
+      TZ: Asia/Shanghai
+    ports:
+      - "9212:9212"
+    volumes:
+      # 配置文件
+      - /home/docker/ruoyi-external/logs/:/ruoyi/customer/logs
+      # skywalking 探针
+      - /home/docker/skywalking/agent/:/ruoyi/skywalking/agent
+    privileged: true
+    network_mode: "host"
   ruoyi-gen:
     image: ruoyi/ruoyi-gen:2.4.1
     container_name: ruoyi-gen