5 Комити 100d56a68e ... 52a94bb1e7

Аутор SHA1 Порука Датум
  肖路 52a94bb1e7 Merge remote-tracking branch 'origin/master' into master пре 2 недеља
  肖路 e6f5eb4022 feat(external): 新增外部商品管理和审核功能 пре 2 недеља
  肖路 45d4fb5f46 Merge remote-tracking branch 'origin/master' into master пре 3 недеља
  肖路 cfdce2862f Merge remote-tracking branch 'origin/master' into master пре 3 недеља
  肖路 e76b9e8662 fix(order): 修复订单审批流程初始化日志记录问题 пре 3 недеља
50 измењених фајлова са 837 додато и 191 уклоњено
  1. 86 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/domain/ExternalProductDto.java
  2. 10 0
      ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/service/RemoteExternalProductService.java
  3. 16 5
      ruoyi-auth/src/main/java/org/dromara/auth/controller/Auth2Controller.java
  4. 10 4
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  5. 39 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/ExternalProductController.java
  6. 11 7
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/controller/zhongche/ZhongChePullController.java
  7. 5 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalItem.java
  8. 26 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalProduct.java
  9. 6 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalProductCategory.java
  10. 6 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalPushPoolLog.java
  11. 5 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalItemBo.java
  12. 25 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalProductBo.java
  13. 17 10
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalProductCategoryBo.java
  14. 6 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalPushPoolLogBo.java
  15. 10 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalItemVo.java
  16. 12 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductCategoryVo.java
  17. 18 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductVo.java
  18. 12 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalPushPoolLogVo.java
  19. 21 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/dubbo/RemoteExternalProductServiceImpl.java
  20. 1 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/handler/ProductPushStrategy.java
  21. 48 12
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/handler/impl/ZhongChePushStrategy.java
  22. 1 1
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/handler/impl/ZhongZhiPushStrategy.java
  23. 1 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalItemServiceImpl.java
  24. 15 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalProductCategoryServiceImpl.java
  25. 2 2
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalProductServiceImpl.java
  26. 1 0
      ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalPushPoolLogServiceImpl.java
  27. 6 0
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/pc/PcOrderFlowController.java
  28. 4 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowServiceImpl.java
  29. 3 1
      ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java
  30. 44 11
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBaseController.java
  31. 16 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProtocolProductsController.java
  32. 1 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/DiyProductController.java
  33. 9 4
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/MyProductController.java
  34. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ProtocolProducts.java
  35. 45 20
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBaseBo.java
  36. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProtocolProductsBo.java
  37. 25 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBaseVo.java
  38. 6 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductCategoryVo.java
  39. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProtocolProductsVo.java
  40. 26 3
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java
  41. 185 95
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
  42. 9 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductCategoryServiceImpl.java
  43. 4 1
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductPoolLinkServiceImpl.java
  44. 2 2
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductPoolServiceImpl.java
  45. 3 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProtocolProductsServiceImpl.java
  46. 4 4
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductPoolMapper.xml
  47. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ProductTaxrate.java
  48. 3 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ProductTaxrateBo.java
  49. 2 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProductTaxrateVo.java
  50. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteErpSystemServiceImpl.java

+ 86 - 0
ruoyi-api/ruoyi-api-external/src/main/java/org/dromara/external/api/domain/ExternalProductDto.java

@@ -0,0 +1,86 @@
+package org.dromara.external.api.domain;
+
+import lombok.Data;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+@Data
+public class ExternalProductDto implements Serializable {
+
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    private Long id;
+
+    /**
+     * 商品id
+     */
+    private Long productId;
+
+    /**
+     * 商品名称
+     */
+    private String itemName;
+
+    /**
+     * 商品编号
+     */
+    private String productNo;
+
+    /**
+     * 项目id
+     */
+    private Long itemId;
+
+    /**
+     * 分类id
+     */
+    private Long categoryId;
+
+    /**
+     * 外部分类id
+     */
+    private Long externalCategoryId;
+
+    /**
+     * 推送状态 0未推送,1已推送
+     */
+    private Long pushStatus;
+
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /**
+     *  第三方价格
+     * */
+    private BigDecimal externalPrice;
+
+    /**
+     * 商品状态:1=已上架,0=下架
+     * */
+    private Integer productStatus;
+
+
+    /**
+     * 第三方商品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+    private Integer auditStatus;
+
+    /**
+     * 审核意见
+     */
+    private String auditReason;
+
+    /**
+     * 对接状态 0未对接,1已对接
+     */
+    private Integer connectStatus;
+
+}

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

@@ -1,5 +1,9 @@
 package org.dromara.external.api.service;
 
+import org.dromara.external.api.domain.ExternalProductDto;
+
+import java.util.List;
+
 /**
  * @author
  * @date 2026/1/14 下午4:58
@@ -10,4 +14,10 @@ public interface RemoteExternalProductService {
     * 获取商品的对接状态
     * */
     Boolean getProductDockingStatus(Long productId,String itemKey);
+
+    /**
+    * 获取项目中的商品
+    * */
+    List<ExternalProductDto> getExternalProductList(Long itemId);
+
 }

+ 16 - 5
ruoyi-auth/src/main/java/org/dromara/auth/controller/Auth2Controller.java

@@ -42,12 +42,16 @@ public class Auth2Controller {
 
     // ========== 读取yml中的真实公私钥(直接复制使用) ==========
 
+    //测试环境
     //电商私钥
-    private final static String DEVELOPER_PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgpQdXwMi21Mg1FhWad2AQLOwfNiDHgwhootau0YerQbagCgYIKoEcz1UBgi2hRANCAATVjJs6XRAMTZ72G6aWbgCAjfAnW0j5R9VFnHySTiF8+1mOisc3xOOr9w/Tu3hixzL5H2gVyLzHDRWkFtyeVqrX";
-
+//    private final static String DEVELOPER_PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgpQdXwMi21Mg1FhWad2AQLOwfNiDHgwhootau0YerQbagCgYIKoEcz1UBgi2hRANCAATVjJs6XRAMTZ72G6aWbgCAjfAnW0j5R9VFnHySTiF8+1mOisc3xOOr9w/Tu3hixzL5H2gVyLzHDRWkFtyeVqrX";
+//    //企采公钥
+//    private final static String DEVELOPER_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEmUrB5ByAeb8jHayC7vbddqBFDIEsf1cpNO1qJttZ17xlDagVB/tBFasPr/x0+OWf2kimTKah2NGCYarymD1R5Q==";
+    //正式环境
+    //电商私钥
+    private final static String DEVELOPER_PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgQu0H97EPqkgz1YS5LkzZNmkG3mS5Er8rJ2LSoJtuOlGgCgYIKoEcz1UBgi2hRANCAARP6NYwTHpW2QTL8A2f2hpgunEpDVkJBhErBQPLqNS/Si5Q+9I9wUpCYdk1EvB5Hw6yzkE4bYk5IZM1j+/SnNFn";
     //企采公钥
-    private final static String DEVELOPER_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEmUrB5ByAeb8jHayC7vbddqBFDIEsf1cpNO1qJttZ17xlDagVB/tBFasPr/x0+OWf2kimTKah2NGCYarymD1R5Q==";
-
+    private final static String DEVELOPER_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE9ITEKJdH9o1K9AeQYY7zNMo/q5/cdce+9jbawURTPEpBKAx4VkB+lRkb5e5YL+Be4pPM464rPvLyfqGNJvL6uQ==";
 
     /**
      * 获取 Access Token  ZHONGZHI
@@ -78,6 +82,13 @@ public class Auth2Controller {
     }
     /**
      * 获取 Access Token  ZHONGChe
+     * 注册地址:武汉市硚口区古田二路长丰村长丰乡15栋1号5室
+     * 供应商名称:优易达(武汉)有限公司
+     * 管理员手机号:18062697722
+     * 管理员名称:刘洋
+     * 电商系统域名(生产):apipre.yoe365.com
+     * 登录用户名:api_zczc_202403166035
+     * 登陆密码:brsa1odzd28xnqz4
      * @return 包含 access_token 和 expires_at 的 Result,失败则 success=false
      */
     @PostMapping("/zhongche/access_token")
@@ -192,7 +203,7 @@ public class Auth2Controller {
         System.out.println("生成的签名: " + sign);
 
         // ===== 3️⃣ 验签 =====
-        boolean verifyResult = SignParamUtils.verifyRequestSign(bo,"MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1YybOl0QDE2e9humlm4AgI3wJ1tI+UfVRZx8kk4hfPtZjorHN8Tjq/cP07t4Yscy+R9oFci8xw0VpBbcnlaq1w==" );
+        boolean verifyResult = SignParamUtils.verifyRequestSign(bo,"MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAET+jWMEx6VtkEy/ANn9oaYLpxKQ1ZCQYRKwUDy6jUv0ouUPvSPcFKQmHZNRLweR8Oss5BOG2JOSGTNY/v0pzRZw==" );
 
         System.out.println("验签结果: " + verifyResult);
     }

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

@@ -105,9 +105,8 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "sys_user",
         "statement_invoice",
         "statement_invoice_detail",
-        "statement_invoice_product"
-
-
+        "statement_invoice_product",
+        "external_"
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法
     ));
 
@@ -221,7 +220,14 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         }
 
         // 前缀匹配
-        return tableName.startsWith("qrtz_") || tableName.startsWith("product_") || tableName.startsWith("com_") || tableName.startsWith("supplier_") || tableName.startsWith("flow_") || tableName.startsWith("order_");
+        return tableName.startsWith("qrtz_")
+            || tableName.startsWith("product_")
+            || tableName.startsWith("com_")
+            || tableName.startsWith("supplier_")
+            || tableName.startsWith("flow_")
+            || tableName.startsWith("order_")
+            || tableName.startsWith("external_")
+            ;
     }
 
     /**

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

@@ -1,11 +1,14 @@
 package org.dromara.external.controller;
 
+import java.sql.Wrapper;
 import java.util.List;
 
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import jakarta.servlet.http.HttpServletResponse;
 import jakarta.validation.constraints.*;
 import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.external.domain.ExternalProduct;
 import org.dromara.external.handler.ProductPushStrategyFactory;
 import org.dromara.product.api.domain.ProductVo;
 import org.springframework.web.bind.annotation.*;
@@ -145,6 +148,42 @@ public class ExternalProductController extends BaseController {
         return toAjax(externalProductService.saveExternalBatch(itemId,boList));
     }
 
+    /**
+    * 获取项目的商品id
+    * */
+    @GetMapping("/getProjectProductIds/{itemId}")
+    public R<List<Long>> getProjectProductIds(@PathVariable Long itemId) {
+        List<ExternalProduct> externalProducts = externalProductService.list(Wrappers.lambdaQuery(ExternalProduct.class).eq(ExternalProduct::getItemId, itemId));
+        return R.ok(externalProducts.stream().map(ExternalProduct::getProductId).toList());
+    }
+
+    /**
+    * 批量更新第三方价格
+    * */
+    @PostMapping("/updateProductPrice")
+    public R<Void> updateProductPrice(@Validated @RequestBody ExternalProductBo bo) {
+            externalProductService.update(Wrappers.lambdaUpdate(ExternalProduct.class)
+                .eq(ExternalProduct::getProductId, bo.getProductId())
+                .set(ExternalProduct::getItemId, bo.getItemId())
+                .set(ExternalProduct::getExternalPrice, bo.getExternalPrice()));
+        return R.ok();
+    }
+
+    /**
+    * 批量审核项目商品
+    * */
+    @PostMapping("/batchReview")
+    public R<Void> batchReview(@Validated @RequestBody List<ExternalProductBo> externalProductBos) {
+        externalProductBos.forEach(bo -> {
+            externalProductService.update(Wrappers.lambdaUpdate(ExternalProduct.class)
+                .eq(ExternalProduct::getProductId, bo.getProductId())
+                .set(ExternalProduct::getItemId, bo.getItemId())
+                .set(ExternalProduct::getAuditStatus, bo.getAuditStatus())
+                .set(ExternalProduct::getAuditReason, bo.getAuditReason())
+            );
+        });
+        return R.ok();
+    }
 
 
 

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

@@ -51,16 +51,20 @@ import java.util.List;
 @RequestMapping("/api")
 public class ZhongChePullController {
 
+    //正式环境
     // 中车地区查询接口地址(替换为真实域名)
-    private static final String AREA_QUERY_URL = "https://supply-test.crrcgo.cc/mallapi";
+    private static final String AREA_QUERY_URL = "https://supply.crrcgo.cc/mallapi";
     // 中车提供的配置(替换为真实值)
-    private static final String CLIENT_ID = "KFZAVuIyC56";
-    //正式环境
-    /*private static final String PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgpQdXwMi21Mg1FhWad2AQLOwfNiDHgwhootau0YerQbagCgYIKoEcz1UBgi2hRANCAATVjJs6XRAMTZ72G6aWbgCAjfAnW0j5R9VFnHySTiF8+1mOisc3xOOr9w/Tu3hixzL5H2gVyLzHDRWkFtyeVqrX"; // 电商平台私钥
-    private static final String ZC_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAEmUrB5ByAeb8jHayC7vbddqBFDIEsf1cpNO1qJttZ17xlDagVB/tBFasPr/x0+OWf2kimTKah2NGCYarymD1R5Q=="; // 中车公钥*/
+    private static final String CLIENT_ID = "KFZnKGiDsJ7";
+    private static final String PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgQu0H97EPqkgz1YS5LkzZNmkG3mS5Er8rJ2LSoJtuOlGgCgYIKoEcz1UBgi2hRANCAARP6NYwTHpW2QTL8A2f2hpgunEpDVkJBhErBQPLqNS/Si5Q+9I9wUpCYdk1EvB5Hw6yzkE4bYk5IZM1j+/SnNFn"; // 电商平台私钥
+    private static final String ZC_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAET+jWMEx6VtkEy/ANn9oaYLpxKQ1ZCQYRKwUDy6jUv0ouUPvSPcFKQmHZNRLweR8Oss5BOG2JOSGTNY/v0pzRZw=="; // 中车公钥
     //测试环境
-    private static final String PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgpQdXwMi21Mg1FhWad2AQLOwfNiDHgwhootau0YerQbagCgYIKoEcz1UBgi2hRANCAATVjJs6XRAMTZ72G6aWbgCAjfAnW0j5R9VFnHySTiF8+1mOisc3xOOr9w/Tu3hixzL5H2gVyLzHDRWkFtyeVqrX"; // 电商平台私钥
-    private static final String ZC_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1YybOl0QDE2e9humlm4AgI3wJ1tI+UfVRZx8kk4hfPtZjorHN8Tjq/cP07t4Yscy+R9oFci8xw0VpBbcnlaq1w=="; // 中车公钥
+    // 中车地区查询接口地址(替换为真实域名)
+//    private static final String AREA_QUERY_URL = "https://supply-test.crrcgo.cc/mallapi/";
+//    // 中车提供的配置(替换为真实值)
+//    private static final String CLIENT_ID = "KFZAVuIyC56";
+//    private static final String PRIVATE_KEY = "MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQgpQdXwMi21Mg1FhWad2AQLOwfNiDHgwhootau0YerQbagCgYIKoEcz1UBgi2hRANCAATVjJs6XRAMTZ72G6aWbgCAjfAnW0j5R9VFnHySTiF8+1mOisc3xOOr9w/Tu3hixzL5H2gVyLzHDRWkFtyeVqrX"; // 电商平台私钥
+//    private static final String ZC_PUBLIC_KEY = "MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE1YybOl0QDE2e9humlm4AgI3wJ1tI+UfVRZx8kk4hfPtZjorHN8Tjq/cP07t4Yscy+R9oFci8xw0VpBbcnlaq1w=="; // 中车公钥
     //企采公钥
     private static final String VERSION = "1.0.0";
 

+ 5 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalItem.java

@@ -27,6 +27,11 @@ public class ExternalItem extends TenantEntity {
     @TableId(value = "id")
     private Long id;
 
+    /**
+     * 项目负责人id
+     * */
+    private Long purchaseId;
+
     /**
      * 项目logo
      */

+ 26 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalProduct.java

@@ -85,4 +85,30 @@ public class ExternalProduct extends TenantEntity {
     private Integer productStatus;
 
 
+    /**
+     * 第三方商品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+    private Integer auditStatus;
+
+    /**
+     * 审核意见
+     */
+    private String auditReason;
+    /**
+     * 对接状态 0未对接,1已对接
+     */
+    private Integer connectStatus;
+
+    /**
+     * 总库存
+     * */
+    private Integer totalInventory;
+    /**
+     * 可供库存
+     * */
+    private Integer availableInventory;
+    /**
+     * 起订量
+     * */
+    private Integer minOrderQuantity;
 }

+ 6 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalProductCategory.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 import java.io.Serial;
+import java.math.BigDecimal;
 
 /**
  * 产品分类对象 external_product_category
@@ -93,5 +94,10 @@ public class ExternalProductCategory extends TenantEntity {
      */
     private String remark;
 
+    /**
+     * 折扣率
+     */
+    private BigDecimal discountRate;
+
 
 }

+ 6 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/ExternalPushPoolLog.java

@@ -22,7 +22,7 @@ public class ExternalPushPoolLog extends TenantEntity {
     private static final long serialVersionUID = 1L;
 
     /**
-     * 
+     *
      */
     @TableId(value = "id")
     private Long id;
@@ -37,6 +37,11 @@ public class ExternalPushPoolLog extends TenantEntity {
      */
     private Long poolId;
 
+    /**
+    * 商品id
+    * */
+    private Long productId;
+
     /**
      * 操作人id
      */

+ 5 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalItemBo.java

@@ -25,6 +25,11 @@ public class ExternalItemBo extends BaseEntity {
      */
     private Long id;
 
+    /**
+     * 项目负责人id
+     * */
+    private Long purchaseId;
+
     /**
      * 项目logo
      */

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

@@ -76,7 +76,32 @@ public class ExternalProductBo extends BaseEntity {
     * */
     private Integer productStatus;
 
+    /**
+     * 第三方商品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+    private Integer auditStatus;
 
+    /**
+     * 审核意见
+     */
+    private String auditReason;
+
+    /**
+     * 对接状态 0未对接,1已对接
+     */
+    private Integer connectStatus;
+    /**
+    * 总库存
+    * */
+    private Integer totalInventory;
+    /**
+    * 可供库存
+    * */
+    private Integer availableInventory;
+    /**
+    * 起订量
+    * */
+    private Integer minOrderQuantity;
 
 
 }

+ 17 - 10
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalProductCategoryBo.java

@@ -9,6 +9,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
 
+import java.math.BigDecimal;
+
 /**
  * 产品分类业务对象 external_product_category
  *
@@ -34,31 +36,31 @@ public class ExternalProductCategoryBo extends BaseEntity {
     /**
      * 原系统分类id
      */
-    @NotNull(message = "原系统分类id不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotNull(message = "原系统分类id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long productCategoryId;
 
     /**
      * 分类编号
      */
-    @NotBlank(message = "分类编号不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "分类编号不能为空", groups = { AddGroup.class, EditGroup.class })
     private String categoryNo;
 
     /**
      * 分类名称
      */
-    @NotBlank(message = "分类名称不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "分类名称不能为空", groups = { AddGroup.class, EditGroup.class })
     private String categoryName;
 
     /**
      * 父级分类ID
      */
-    @NotNull(message = "父级分类ID不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotNull(message = "父级分类ID不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long parentId;
 
     /**
      * 祖籍列表
      */
-    @NotBlank(message = "祖籍列表不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "祖籍列表不能为空", groups = { AddGroup.class, EditGroup.class })
     private String ancestors;
 
     /**
@@ -69,32 +71,37 @@ public class ExternalProductCategoryBo extends BaseEntity {
     /**
      * 拼音码(用于快速检索)
      */
-    @NotBlank(message = "拼音码(用于快速检索)不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "拼音码(用于快速检索)不能为空", groups = { AddGroup.class, EditGroup.class })
     private String pyCode;
 
     /**
      * 分类描述
      */
-    @NotBlank(message = "分类描述不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "分类描述不能为空", groups = { AddGroup.class, EditGroup.class })
     private String classDescription;
 
     /**
      * 数据来源
      */
-    @NotBlank(message = "数据来源不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "数据来源不能为空", groups = { AddGroup.class, EditGroup.class })
     private String dataSource;
 
     /**
      * 所属平台(0=Web, 1=小程序)
      */
-    @NotNull(message = "所属平台(0=Web, 1=小程序)不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotNull(message = "所属平台(0=Web, 1=小程序)不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long platform;
 
     /**
      * 备注
      */
-    @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+//    @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
     private String remark;
 
+    /**
+     * 折扣率
+     */
+    private BigDecimal discountRate;
+
 
 }

+ 6 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/bo/ExternalPushPoolLogBo.java

@@ -21,7 +21,7 @@ import jakarta.validation.constraints.*;
 public class ExternalPushPoolLogBo extends BaseEntity {
 
     /**
-     * 
+     *
      */
     private Long id;
 
@@ -37,6 +37,11 @@ public class ExternalPushPoolLogBo extends BaseEntity {
     @NotNull(message = "商品池id不能为空", groups = { AddGroup.class, EditGroup.class })
     private Long poolId;
 
+    /**
+     * 商品id
+     * */
+    private Long productId;
+
     /**
      * 操作人id
      */

+ 10 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalItemVo.java

@@ -35,6 +35,11 @@ public class ExternalItemVo implements Serializable {
     @ExcelProperty(value = "项目id")
     private Long id;
 
+    /**
+     * 项目负责人id
+     * */
+    private Long purchaseId;
+
     /**
      * 项目logo
      */
@@ -83,6 +88,11 @@ public class ExternalItemVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+    * 创建时间
+    * */
+    private Date createTime;
+
     /**
      * 商品数量
      */

+ 12 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductCategoryVo.java

@@ -10,6 +10,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -109,5 +110,16 @@ public class ExternalProductCategoryVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+     * 上级分类名称
+     * */
+    @ExcelProperty(value = "上级分类名称")
+    private String parentCategoryName;
+
+    /**
+     * 折扣率
+     */
+    private BigDecimal discountRate;
+
 
 }

+ 18 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalProductVo.java

@@ -424,6 +424,24 @@ public class ExternalProductVo implements Serializable {
      */
     private String externalCategoryName;
 
+    /**
+     * 第三方商品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+    private Integer auditStatus;
+
+    /**
+     * 审核意见
+     */
+    private String auditReason;
+
+    /**
+     * 对接状态 0未对接,1已对接
+     */
+    private Integer connectStatus;
+    /**
+     * 可供库存
+     * */
+    private Integer availableInventory;
 
 
 }

+ 12 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/domain/vo/ExternalPushPoolLogVo.java

@@ -29,7 +29,7 @@ public class ExternalPushPoolLogVo implements Serializable {
     private static final long serialVersionUID = 1L;
 
     /**
-     * 
+     *
      */
     @ExcelProperty(value = "")
     private Long id;
@@ -46,6 +46,11 @@ public class ExternalPushPoolLogVo implements Serializable {
     @ExcelProperty(value = "商品池id")
     private Long poolId;
 
+    /**
+     * 商品id
+     * */
+    private Long productId;
+
     /**
      * 操作人id
      */
@@ -77,5 +82,11 @@ public class ExternalPushPoolLogVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+    * 创建时间
+    * */
+    @ExcelProperty(value = "创建时间")
+    private Date createTime;
+
 
 }

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

@@ -1,10 +1,12 @@
 package org.dromara.external.dubbo;
 
+import cn.hutool.core.bean.BeanUtil;
 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.domain.ExternalProductDto;
 import org.dromara.external.api.service.RemoteExternalProductService;
 import org.dromara.external.domain.ExternalItem;
 import org.dromara.external.domain.ExternalProduct;
@@ -12,6 +14,8 @@ import org.dromara.external.service.IExternalItemService;
 import org.dromara.external.service.IExternalProductService;
 import org.springframework.stereotype.Service;
 
+import java.util.List;
+
 /**
  * @author
  * @date 2026/1/14 下午5:02
@@ -49,4 +53,21 @@ public class RemoteExternalProductServiceImpl implements RemoteExternalProductSe
         );
         return ObjectUtil.isNotEmpty(externalProduct);
     }
+
+    /**
+     * 获取项目中的商品
+     *
+     * @param itemId
+     */
+    @Override
+    public List<ExternalProductDto> getExternalProductList(Long itemId) {
+        List<ExternalProduct> externalProducts = externalProductService.list(Wrappers.lambdaQuery(ExternalProduct.class)
+            .eq(ExternalProduct::getItemId, itemId)
+        );
+        if(ObjectUtil.isEmpty(externalProducts)){
+            return List.of();
+        }
+
+        return BeanUtil.copyToList(externalProducts, ExternalProductDto.class);
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/handler/ProductPushStrategy.java

@@ -9,5 +9,5 @@ public interface ProductPushStrategy {
     /**
      * 推送商品
      */
-    void push(List<ExternalProduct> products);
+    void push( Long itemId,List<ExternalProduct> products);
 }

+ 48 - 12
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/handler/impl/ZhongChePushStrategy.java

@@ -6,6 +6,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import lombok.RequiredArgsConstructor;
 import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.exception.api.ZhongcheException;
 import org.dromara.common.core.utils.StringUtils;
 import org.dromara.external.api.zhongche.domain.GoodsImportItem;
 import org.dromara.external.api.zhongche.domain.bo.GoodsImportBo;
@@ -13,10 +14,12 @@ import org.dromara.external.api.zhongche.domain.vo.GoodsImportVo;
 import org.dromara.external.controller.zhongche.ZhongChePullController;
 import org.dromara.external.domain.ExternalProduct;
 import org.dromara.external.domain.ExternalProductCategory;
+import org.dromara.external.domain.ExternalPushPoolLog;
 import org.dromara.external.domain.vo.ExternalProductVo;
 import org.dromara.external.handler.ProductPushStrategy;
 import org.dromara.external.mapper.ExternalProductMapper;
 import org.dromara.external.service.IExternalProductCategoryService;
+import org.dromara.external.service.IExternalPushPoolLogService;
 import org.dromara.product.api.RemoteProductService;
 import org.dromara.product.api.domain.ProductVo;
 import org.dromara.product.api.domain.zhongche.dto.ProductAggregateDto;
@@ -41,11 +44,12 @@ public class ZhongChePushStrategy implements ProductPushStrategy {
 
     private final IExternalProductCategoryService externalProductCategoryService;
 
+    private final IExternalPushPoolLogService externalPushPoolLogService;
+
     private final ObjectMapper objectMapper;
 
     @Override
-    @Transactional(rollbackFor = Exception.class)
-    public void push(List<ExternalProduct> products) {
+    public void push( Long itemId,List<ExternalProduct> products) {
         String username = "admin";
         List<ExternalProductVo> productVoList = new ArrayList<>();
         for (ExternalProduct product : products) {
@@ -164,20 +168,52 @@ public class ZhongChePushStrategy implements ProductPushStrategy {
             GoodsImportBo bo = new GoodsImportBo();
             bo.setAccount(username);
             bo.setGoods(batchGoods);
-            GoodsImportVo goodsImportVo = zhongChePullController.egoodsImport(bo);
-            if (goodsImportVo.getResult() == 1) {
-                externalProductMapper.update(
-                    Wrappers.lambdaUpdate(ExternalProduct.class)
-                        .set(ExternalProduct::getPushStatus, 1)
-                        .in(ExternalProduct::getId, productIds)
-                );
-            } else {
+            GoodsImportVo goodsImportVo = new GoodsImportVo();
+            try {
+                goodsImportVo = zhongChePullController.egoodsImport(bo);
+                if (goodsImportVo.getResult() == 1) {
+                    externalProductMapper.update(
+                        Wrappers.lambdaUpdate(ExternalProduct.class)
+                            .set(ExternalProduct::getPushStatus, 1)
+                            .in(ExternalProduct::getId, productIds)
+                            .eq(ExternalProduct::getItemId, itemId)
+                    );
+                }else {
+                    externalProductMapper.update(
+                        Wrappers.lambdaUpdate(ExternalProduct.class)
+                            .set(ExternalProduct::getConnectStatus, 1)
+                            .set(ExternalProduct::getPushStatus, 2)
+                            .set(ExternalProduct::getRemark, goodsImportVo.getMessage())
+                            .in(ExternalProduct::getId, productIds)
+                            .eq(ExternalProduct::getItemId, itemId)
+                    );
+                    for (Long productId : productIds) {
+                        ExternalPushPoolLog externalPushPoolLog = new ExternalPushPoolLog();
+                        externalPushPoolLog.setProductId(productId);
+                        externalPushPoolLog.setItemId(itemId);
+                        externalPushPoolLog.setPushStatus("1");
+                        externalPushPoolLog.setRemark(goodsImportVo.getMessage());
+                        externalPushPoolLogService.save(externalPushPoolLog);
+                    }
+                }
+            } catch (ZhongcheException e) {
                 externalProductMapper.update(
                     Wrappers.lambdaUpdate(ExternalProduct.class)
-                        .set(ExternalProduct::getPushStatus, 3)
-                        .set(ExternalProduct::getRemark, goodsImportVo.getMessage())
+                        .set(ExternalProduct::getConnectStatus, 1)
+                        .set(ExternalProduct::getPushStatus, 2)
+                        .set(ExternalProduct::getRemark, e.getMessage())
                         .in(ExternalProduct::getId, productIds)
+                        .eq(ExternalProduct::getItemId, itemId)
                 );
+                for (Long productId : productIds) {
+                    ExternalPushPoolLog externalPushPoolLog = new ExternalPushPoolLog();
+                    externalPushPoolLog.setItemId(itemId);
+                    externalPushPoolLog.setProductId(productId);
+                    externalPushPoolLog.setPushStatus("1");
+                    externalPushPoolLog.setReason(e.getMessage());
+                    externalPushPoolLogService.save(externalPushPoolLog);
+                }
+                throw e;
             }
         }
     }

+ 1 - 1
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/handler/impl/ZhongZhiPushStrategy.java

@@ -10,7 +10,7 @@ import java.util.List;
 public class ZhongZhiPushStrategy implements ProductPushStrategy {
 
     @Override
-    public void push(List<ExternalProduct> products) {
+    public void push(Long itemId,List<ExternalProduct> products) {
 
         for (ExternalProduct product : products) {
             // 调用中职API

+ 1 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalItemServiceImpl.java

@@ -68,6 +68,7 @@ public class ExternalItemServiceImpl  extends ServiceImpl<ExternalItemMapper, Ex
         LambdaQueryWrapper<ExternalItem> lqw = buildQueryWrapper(bo);
         Page<ExternalItemVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
         result.getRecords().forEach(item -> {
+
             OrderStatusCountDto orderStatusCount = remoteOrderInfoService.getOrderStatusCount(item.getItemKey());
             item.setProductCount(externalProductMapper.selectCount(Wrappers.lambdaQuery(ExternalProduct.class).eq(ExternalProduct::getItemId, item.getId())));
             item.setOrderCount(orderStatusCount.getOrderCount());

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

@@ -2,6 +2,7 @@ package org.dromara.external.service.impl;
 
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.lang.tree.Tree;
+import cn.hutool.core.util.ObjectUtil;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import org.dromara.common.core.utils.MapstructUtils;
 import org.dromara.common.core.utils.StringUtils;
@@ -59,6 +60,20 @@ public class ExternalProductCategoryServiceImpl  extends ServiceImpl<ExternalPro
     public TableDataInfo<ExternalProductCategoryVo> queryPageList(ExternalProductCategoryBo bo, PageQuery pageQuery) {
         LambdaQueryWrapper<ExternalProductCategory> lqw = buildQueryWrapper(bo);
         Page<ExternalProductCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        result.getRecords().forEach(productCategory -> {
+            productCategory.setParentCategoryName("");
+            //通过祖籍列表查询上级分类名称
+            if (StringUtils.isNotBlank(productCategory.getAncestors())) {
+                for (String categoryId : productCategory.getAncestors().split(",")) {
+                    ExternalProductCategory externalProductCategory = baseMapper.selectById(Long.valueOf(categoryId));
+                    if (ObjectUtil.isNotEmpty(externalProductCategory)) {
+                        productCategory.setParentCategoryName(productCategory.getParentCategoryName()+"-"+externalProductCategory.getCategoryName());
+                    }
+
+                }
+
+            }
+        });
         return TableDataInfo.build(result);
     }
 

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

@@ -211,7 +211,6 @@ public class ExternalProductServiceImpl  extends ServiceImpl<ExternalProductMapp
      * @return 推送成功数量
      */
     @Override
-    @Transactional(rollbackFor = Exception.class)
     public int batchPush(Long[] ids) {
         List<ExternalProduct> externalProducts = baseMapper.selectList(new LambdaQueryWrapper<ExternalProduct>()
             .in(ExternalProduct::getId, ids));
@@ -244,7 +243,7 @@ public class ExternalProductServiceImpl  extends ServiceImpl<ExternalProductMapp
             strategyFactory.getStrategy(itemKey);
 
         // 5️⃣ 执行推送
-        strategy.push(externalProducts);
+        strategy.push(itemId,externalProducts);
         return baseMapper.update(Wrappers.lambdaUpdate(ExternalProduct.class)
             .set(ExternalProduct::getPushStatus, 1)
             .in(ExternalProduct::getId, ids));
@@ -366,6 +365,7 @@ public class ExternalProductServiceImpl  extends ServiceImpl<ExternalProductMapp
                 externalProduct.setItemId(itemId);
                 externalProduct.setProductId(vo.getId());
                 externalProduct.setProductStatus(vo.getProductStatus());
+                externalProduct.setAuditStatus(1);
                 insertList.add(externalProduct);
             }
         }

+ 1 - 0
ruoyi-modules/ruoyi-external/src/main/java/org/dromara/external/service/impl/ExternalPushPoolLogServiceImpl.java

@@ -77,6 +77,7 @@ public class ExternalPushPoolLogServiceImpl  extends ServiceImpl<ExternalPushPoo
         lqw.orderByAsc(ExternalPushPoolLog::getId);
         lqw.eq(bo.getItemId() != null, ExternalPushPoolLog::getItemId, bo.getItemId());
         lqw.eq(bo.getPoolId() != null, ExternalPushPoolLog::getPoolId, bo.getPoolId());
+        lqw.eq(bo.getProductId() != null, ExternalPushPoolLog::getProductId, bo.getProductId());
         lqw.eq(bo.getOperatorId() != null, ExternalPushPoolLog::getOperatorId, bo.getOperatorId());
         lqw.eq(StringUtils.isNotBlank(bo.getPushStatus()), ExternalPushPoolLog::getPushStatus, bo.getPushStatus());
         lqw.eq(StringUtils.isNotBlank(bo.getStatus()), ExternalPushPoolLog::getStatus, bo.getStatus());

+ 6 - 0
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/controller/pc/PcOrderFlowController.java

@@ -108,8 +108,14 @@ public class PcOrderFlowController extends BaseController {
     public R<String> startOrderFlow(@PathVariable Long id) {
         orderCustomerFlowService.update(Wrappers.lambdaUpdate(OrderCustomerFlow.class)
             .set(OrderCustomerFlow::getStatus, "0")
+            .eq(OrderCustomerFlow::getCustomerId, LoginHelper.getLoginUser().getCustomerId())
             .eq(OrderCustomerFlow::getId, id)
         );
+        orderCustomerFlowService.update(Wrappers.lambdaUpdate(OrderCustomerFlow.class)
+            .set(OrderCustomerFlow::getStatus, "1")
+            .eq(OrderCustomerFlow::getCustomerId, LoginHelper.getLoginUser().getCustomerId())
+            .ne(OrderCustomerFlow::getId, id)
+        );
         return R.ok("开启成功");
     }
 

+ 4 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderCustomerFlowServiceImpl.java

@@ -13,6 +13,7 @@ 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.extern.slf4j.Slf4j;
+import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.order.domain.*;
 import org.dromara.order.domain.bo.OrderCustomerFlowLinkBo;
 import org.dromara.order.mapper.OrderMainMapper;
@@ -233,7 +234,9 @@ public class OrderCustomerFlowServiceImpl extends ServiceImpl<OrderCustomerFlowM
     public Boolean initOrderFlow(Long orderId) {
         //查询默认开启的流程
         OrderCustomerFlow flow = baseMapper.selectOne(
-            new LambdaQueryWrapper<OrderCustomerFlow>().eq(OrderCustomerFlow::getStatus, "0")
+            new LambdaQueryWrapper<OrderCustomerFlow>()
+                .eq(OrderCustomerFlow::getCustomerId, LoginHelper.getLoginUser().getCustomerId())
+                .eq(OrderCustomerFlow::getStatus, "0")
                 .orderByDesc(OrderCustomerFlow::getUpdateTime)
                 .last("limit 1")
         );

+ 3 - 1
ruoyi-modules/ruoyi-order/src/main/java/org/dromara/order/service/impl/OrderMainServiceImpl.java

@@ -608,10 +608,12 @@ public class OrderMainServiceImpl extends ServiceImpl<OrderMainMapper, OrderMain
 
             // 4. 如果流程初始化成功,更新订单状态 (注意:这里再次触发了数据库更新)
             if (initOrderFlow) {
+                log.info("成功初始化审批流程,订单ID: {}", orderId);
                 this.update(Wrappers.lambdaUpdate(OrderMain.class)
                     .eq(OrderMain::getId, orderId)
                     .set(OrderMain::getOrderStatus, 1)); // 假设 1 代表某种特定状态,需确认枚举值
-            } else {
+            }else {
+                log.info("失败初始化审批流程,订单ID: {}", orderId);
                 this.update(Wrappers.lambdaUpdate(OrderMain.class)
                     .eq(OrderMain::getId, orderId)
                     .set(OrderMain::getCheckStatus, "1")

+ 44 - 11
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBaseController.java

@@ -60,8 +60,8 @@ public class ProductBaseController extends BaseController {
     }
 
     /**
-    * 获取商品各个状态数量
-    * */
+     * 获取商品各个状态数量
+     */
     @GetMapping("/getProductStatusCount")
     public R<StatusCountVo> getProductStatusCount() {
         return R.ok(productBaseService.getProductStatusCount());
@@ -125,6 +125,14 @@ public class ProductBaseController extends BaseController {
         return toAjax(productBaseService.deleteWithValidByIds(List.of(ids), true));
     }
 
+    /**
+     * 更新商品库存
+     */
+    @PostMapping("/updateStock")
+    public R<Void> updateStock(@Validated @RequestBody ProductBaseBo bo) {
+        return toAjax(productBaseService.updateStock(bo));
+    }
+
     /**
      * 获取分类树列表
      */
@@ -161,24 +169,24 @@ public class ProductBaseController extends BaseController {
     }
 
     /**
-    * 获取服务保障信息列表
-    * */
+     * 获取服务保障信息列表
+     */
     @GetMapping("/getServiceList")
     public R<List<ProductEnsureVo>> getServiceList(ProductEnsureBo bo) {
         return R.ok(productEnsureService.queryList(bo));
     }
 
     /**
-    * 获取售后服务信息列表
-    * */
+     * 获取售后服务信息列表
+     */
     @GetMapping("/getAfterSalesList")
     public R<List<ProductAfterSalesVo>> getAfterSalesList(ProductAfterSalesBo bo) {
         return R.ok(productAfterSalesService.queryList(bo));
     }
 
     /**
-    * 获取单位列表
-    * */
+     * 获取单位列表
+     */
     @GetMapping("/getUnitList")
     public R<List<ProductUnitVo>> getUnitList(ProductUnitBo bo) {
         return R.ok(productUnitService.queryList(bo));
@@ -208,7 +216,7 @@ public class ProductBaseController extends BaseController {
 
     /**
      * 商品上下架 状态变更
-     * */
+     */
     @PostMapping("/shelfReview")
     public R<Void> shelfReview(@Validated @RequestBody ProductBaseBo bo) {
         productBaseService.shelfReview(bo);
@@ -216,8 +224,8 @@ public class ProductBaseController extends BaseController {
     }
 
     /**
-    * 商品类型改变
-    * */
+     * 商品类型改变
+     */
     @PostMapping("/changeProductType")
     public R<Void> changeProductType(@Validated @RequestBody ProductBaseBo bo) {
         productBaseService.changeProductType(bo);
@@ -247,4 +255,29 @@ public class ProductBaseController extends BaseController {
     public TableDataInfo<ProductBaseSimpleVo> simpleList(ProductBaseBo bo, PageQuery pageQuery) {
         return productBaseService.querySimplePageList(bo, pageQuery);
     }
+
+    /**
+     * 获取自营商品列表
+     */
+    @GetMapping("/getSelfProductPage")
+    public TableDataInfo<ProductBaseVo> getSelfProductPage(ProductBaseBo bo, PageQuery pageQuery) {
+        return productBaseService.getSelfProductList(bo, pageQuery);
+    }
+
+    /**
+    * 获取精品商品列表
+    * */
+    @GetMapping("/getGoodProductPage")
+    public TableDataInfo<ProductBaseVo> getGoodProductPage(ProductBaseBo bo, PageQuery pageQuery) {
+        return productBaseService.getGoodProductList(bo, pageQuery);
+    }
+
+    /**
+    * 获取项目商品列表
+    * */
+    @GetMapping("/getItemProductPage")
+    public TableDataInfo<ProductBaseVo> getItemProductPage(ProductBaseBo bo, PageQuery pageQuery) {
+        return productBaseService.getItemProductList(bo, pageQuery);
+    }
+
 }

+ 16 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProtocolProductsController.java

@@ -136,4 +136,20 @@ public class ProtocolProductsController extends BaseController {
         );
         return R.ok();
     }
+
+    /**
+    * 批量审核协议商品
+    * */
+    @PostMapping("/batchAudit")
+    public R<Void> batchAudit(@Validated @RequestBody List<ProtocolProductsBo> bo) {
+        for (ProtocolProductsBo item : bo) {
+            protocolProductsService.update(Wrappers.lambdaUpdate(ProtocolProducts.class)
+                .set(ProtocolProducts::getAuditStatus, item.getAuditStatus())
+                .set(ProtocolProducts::getAuditReason, item.getAuditReason())
+                .eq(ProtocolProducts::getProductId, item.getProductId())
+                .eq(ProtocolProducts::getProtocolId, item.getProtocolId())
+            );
+        }
+        return R.ok();
+    }
 }

+ 1 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/DiyProductController.java

@@ -1,5 +1,6 @@
 package org.dromara.product.controller.pc;
 
+import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.lang.tree.Tree;
 import lombok.RequiredArgsConstructor;
 import org.dromara.common.core.domain.R;

+ 9 - 4
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/pc/MyProductController.java

@@ -15,10 +15,7 @@ import org.dromara.product.domain.ProductCollect;
 import org.dromara.product.domain.ProductFavorites;
 import org.dromara.product.domain.ProductShoppingCart;
 import org.dromara.product.domain.bo.*;
-import org.dromara.product.domain.vo.PcProductVo;
-import org.dromara.product.domain.vo.ProcurementProgramVo;
-import org.dromara.product.domain.vo.ProductFavoritesVo;
-import org.dromara.product.domain.vo.ProductShoppingCartExportVo;
+import org.dromara.product.domain.vo.*;
 import org.dromara.product.service.*;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
@@ -203,6 +200,14 @@ public class MyProductController {
     @PostMapping("/addProductShoppingCart")
     public R addProductShoppingCart(@RequestBody ProductShoppingCartBo bo) {
         Long userId = LoginHelper.getUserId();
+        //校验是否存在库存和商品是否上架
+        ProductBaseVo productBaseVo = productBaseService.queryById(bo.getProductId());
+        if (!Objects.equals(productBaseVo.getProductStatus(), 1)) {
+            return R.fail("商品已下架");
+        }
+        if (productBaseVo.getTotalInventory() - bo.getProductNum() < 0) {
+            return R.fail("商品库存不足");
+        }
         //查看是否存在同一个商品
         ProductShoppingCart one = productShoppingCartService.getOne(Wrappers.lambdaQuery(ProductShoppingCart.class)
             .eq(ProductShoppingCart::getUserId, userId)

+ 9 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/ProtocolProducts.java

@@ -85,5 +85,14 @@ public class ProtocolProducts extends TenantEntity {
      */
     private String delFlag;
 
+    /**
+     * 产品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     * */
+    private Integer auditStatus;
+    /**
+     * 审核意见
+     * */
+    private String auditReason;
+
 
 }

+ 45 - 20
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBaseBo.java

@@ -31,8 +31,8 @@ public class ProductBaseBo extends BaseEntity {
     private Long id;
 
     /**
-    * 多个商品
-    * */
+     * 多个商品
+     */
     private String ids;
 
     /**
@@ -70,8 +70,8 @@ public class ProductBaseBo extends BaseEntity {
     private String categoryName;
 
     /**
-    * 分类ids(底级)
-    * */
+     * 分类ids(底级)
+     */
     private String categoryIds;
 
     /**
@@ -108,8 +108,8 @@ public class ProductBaseBo extends BaseEntity {
     private Integer isSelf;
 
     /**
-    * 商品类型 1=默认类型,2精选商品,3=停售商品
-    * */
+     * 商品类型 1=默认类型,2精选商品,3=停售商品
+     */
     private Integer productCategory;
 
     /**
@@ -277,17 +277,17 @@ public class ProductBaseBo extends BaseEntity {
      */
     private java.math.BigDecimal estimatedPurchasePrice;
     /**
-    * 总库存
-    * */
+     * 总库存
+     */
     private Long totalInventory;
     /**
      * 当前可用库存
-     * */
+     */
     private Long nowInventory;
 
     /**
-    * 虚拟库存
-    * */
+     * 虚拟库存
+     */
     private Long virtualInventory;
 
     /**
@@ -311,8 +311,8 @@ public class ProductBaseBo extends BaseEntity {
     private String mobileDetail;
 
     /**
-    * 商品属性
-    * */
+     * 商品属性
+     */
     private String attributesList;
 
     /**
@@ -346,23 +346,48 @@ public class ProductBaseBo extends BaseEntity {
     private String customDetailsJson;
 
     /**
-    * 审核意见
-    * */
+     * 审核意见
+     */
     private String reviewComments;
     /**
-    * 上架意见
-    * */
+     * 上架意见
+     */
     private String shelfComments;
 
     /**
      * 商品多图
-     * */
+     */
     private String imageUrl;
 
     /**
-    * 站点id
-    * */
+     * 站点id
+     */
     private Long siteId;
 
+    /**
+     * 项目id
+     */
+    private Long itemId;
+
+    /**
+     * 是否是上架审核页面 1是 0否
+     */
+    private Integer isShelfAudit;
+
+    /**
+     * 自营精选审核状态  0=待提交,1=待审核,2=审核通过,3=审核驳回
+     */
+    private Integer auditStatus;
+
+    /**
+    * 对接状态 0未对接,1已对接
+     */
+    private Integer connectStatus;
+    /**
+    * 推送状态 0未推送,1已推送, 2推送失败
+    * */
+    private Integer pushStatus;
+
+
 
 }

+ 9 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProtocolProductsBo.java

@@ -108,5 +108,14 @@ public class ProtocolProductsBo extends BaseEntity {
     * */
     private Long productStatus;
 
+    /**
+     * 产品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     * */
+    private Integer auditStatus;
+    /**
+     * 审核意见
+     * */
+    private String auditReason;
+
 
 }

+ 25 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBaseVo.java

@@ -481,6 +481,11 @@ public class ProductBaseVo implements Serializable {
      */
     private Long pushStatus;
 
+    /**
+    * 上架审核评论
+    * */
+    private String shelfComments;
+
     /**
     * 协议价
     * */
@@ -497,4 +502,24 @@ public class ProductBaseVo implements Serializable {
     * 供货时间
     * */
     private String deliveryTime;
+
+    /**
+    * 审核状态 产品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+    * */
+    private Integer auditStatus;
+
+    /**
+    * 审核意见
+    * */
+    private String auditReason;
+
+    /**
+    * 第三方价格
+    * */
+    private BigDecimal externalPrice;
+
+    /**
+     * 对接状态 0未对接,1已对接
+     */
+    private Integer connectStatus;
 }

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

@@ -179,6 +179,12 @@ public class ProductCategoryVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+    * 上级分类名称
+    * */
+    @ExcelProperty(value = "上级分类名称")
+    private String parentCategoryName;
+
     /**
      * 审核人
      */

+ 9 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProtocolProductsVo.java

@@ -98,5 +98,14 @@ public class ProtocolProductsVo implements Serializable {
     @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
     private String status;
 
+    /**
+     * 产品审核状态:0=待提交,1=待审核,2=审核通过,3=审核驳回
+     * */
+    private Integer auditStatus;
+    /**
+     * 审核意见
+     * */
+    private String auditReason;
+
 
 }

+ 26 - 3
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java

@@ -66,6 +66,11 @@ public interface IProductBaseService extends IService<ProductBase>{
      */
     Boolean updateByBo(ProductBaseBo bo);
 
+    /**
+    * 更新库存
+    * */
+    Boolean updateStock(ProductBaseBo bo);
+
     /**
      * 校验并批量删除产品基础信息信息
      *
@@ -135,9 +140,11 @@ public interface IProductBaseService extends IService<ProductBase>{
     void shelfReview(ProductBaseBo bo);
 
     /**
-    * 商品类型改变
-    * */
-    void changeProductType(ProductBaseBo bo);
+     * 商品类型改变
+     *
+     * @return
+     */
+    int changeProductType(ProductBaseBo bo);
 
     /**
     * 行家精选商品列表
@@ -236,4 +243,20 @@ public interface IProductBaseService extends IService<ProductBase>{
     * PC端站点楼层商品列表
      * */
     List<PcProductVo> getSiteFloorProductList(Long floorId);
+
+
+    /**
+    * 获取自营商品列表
+    * */
+    TableDataInfo<ProductBaseVo> getSelfProductList(ProductBaseBo bo, PageQuery pageQuery);
+
+    /**
+    * 获取精品商品列表
+    * */
+    TableDataInfo<ProductBaseVo> getGoodProductList(ProductBaseBo bo, PageQuery pageQuery);
+
+    /**
+    * 获取项目商品列表
+    * */
+    TableDataInfo<ProductBaseVo> getItemProductList(ProductBaseBo bo, PageQuery pageQuery);
 }

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

@@ -4,16 +4,9 @@ import cn.hutool.core.bean.BeanUtil;
 import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.util.ObjectUtil;
-import co.elastic.clients.elasticsearch._types.FieldValue;
-import co.elastic.clients.elasticsearch._types.aggregations.Aggregate;
-import co.elastic.clients.elasticsearch._types.aggregations.Buckets;
-import co.elastic.clients.elasticsearch._types.aggregations.LongTermsAggregate;
-import co.elastic.clients.elasticsearch._types.aggregations.LongTermsBucket;
-import co.elastic.clients.elasticsearch.core.SearchResponse;
 import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
 import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
-import org.apache.dubbo.common.logger.FluentLogger;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.dromara.common.core.exception.ServiceException;
 import org.dromara.common.core.utils.MapstructUtils;
@@ -28,16 +21,14 @@ import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.dromara.common.satoken.utils.LoginHelper;
 import org.dromara.easyes.core.biz.EsPageInfo;
-import org.dromara.easyes.core.biz.SAPageInfo;
 import org.dromara.easyes.core.conditions.select.LambdaEsQueryWrapper;
+import org.dromara.external.api.domain.ExternalProductDto;
 import org.dromara.external.api.service.RemoteExternalProductService;
-import org.dromara.product.api.domain.ProductVo;
 import org.dromara.product.domain.*;
 import org.dromara.product.domain.bo.*;
 import org.dromara.product.domain.vo.*;
 import org.dromara.product.esmapper.ProductEsMapper;
 import org.dromara.product.mapper.*;
-import org.springframework.beans.BeanUtils;
 import org.springframework.boot.ApplicationArguments;
 import org.springframework.boot.ApplicationRunner;
 import org.springframework.stereotype.Service;
@@ -61,33 +52,6 @@ import java.util.stream.Collectors;
 /**
  * 产品基础信息Service业务层处理
  *
- * 性能优化说明(针对200万级别数据量):
- * 1. 启动时ES同步使用分页流式处理,每次只加载1000条数据
- * 2. 提供流式查询API(selectAllListStream)避免OOM
- * 3. 单条查询优化,建议添加缓存
- * 4. 批量删除优化,减少数据库交互
- *
- * 数据库索引建议(必须添加):
- * product_base表:
- *   - idx_product_no: product_no (产品编号,唯一索引)
- *   - idx_brand_id: brand_id (品牌ID)
- *   - idx_category: top_category_id, medium_category_id, bottom_category_id (组合索引)
- *   - idx_status: product_status, product_review_status (状态组合索引)
- *   - idx_create_time: create_time (创建时间)
- *
- * product_extend表:
- *   - idx_product_id: product_id (外键索引)
- *
- * product_price_inventory表:
- *   - PRIMARY KEY: product_id (主键)
- *
- * product_classification表:
- *   - idx_product_id: product_id (外键索引)
- *   - idx_category_id: category_id (分类索引)
- *
- * product_customization表:
- *   - idx_product_id: product_id (外键索引)
- *
  * @author LionLi
  * @date 2025-12-11
  */
@@ -133,7 +97,8 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
     private final ProductSpecialLinkMapper productSpecialLinkMapper;
     private final ClientSiteProductMapper clientSiteProductMapper;
     private final ClientSiteFloorLinkMapper clientSiteFloorLinkMapper;
-
+    private final ProductSelfMapper productSelfMapper;
+    private final ProductExquisiteMapper productExquisiteMapper;
     private final ProductEsMapper esMapper;
 
     @DubboReference
@@ -279,6 +244,9 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
             vo.setSpecificationsCode(extend.getSpecificationsCode());
             vo.setIsCustomize(Long.valueOf(ObjectUtil.isNotEmpty(extend.getIsCustomize())?extend.getIsCustomize():"0"));
             vo.setDeliveryTime(extend.getDeliveryTime());
+            vo.setShelfComments(extend.getShelfComments());
+            vo.setProductNature(extend.getPurchaseManagerNo());
+            vo.setPurchasingPersonnel(extend.getPurchaseNo());
         }
 
         // 3. 查询并填充价格库存信息(product_price_inventory表)
@@ -359,52 +327,6 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         return List.of();
     }
 
-    //    /**
-//     * 分页查询产品基础信息列表
-//     *
-//     * @param bo        查询条件
-//     * @param pageQuery 分页参数
-//     * @return 产品基础信息分页列表
-//     */
-//    @Override
-//    public TableDataInfo<ProductBaseVo> queryPageList(ProductBaseBo bo, PageQuery pageQuery) {
-//        QueryWrapper<ProductBase> lqw = Wrappers.query();
-//        if(ObjectUtil.isNotEmpty(bo.getIds())){
-//            lqw.in( "b.id", bo.getIds().split(","));
-//        }
-//        lqw.ge(ObjectUtil.isNotEmpty(pageQuery.getFirstSeenId()) && pageQuery.getWay() == 0,"b.id", pageQuery.getFirstSeenId());
-//        lqw.gt(ObjectUtil.isNotEmpty(pageQuery.getLastSeenId()) && pageQuery.getWay() == 1,"b.id", pageQuery.getLastSeenId());
-//        lqw.eq(ObjectUtil.isNotEmpty(bo.getBottomCategoryId()),"b.bottom_category_id", bo.getBottomCategoryId());
-//        lqw.eq(ObjectUtil.isNotEmpty(bo.getProductStatus()), "b.product_status", bo.getProductStatus());
-//        lqw.eq(ObjectUtil.isNotEmpty(bo.getProductReviewStatus()),"b.product_review_status", bo.getProductReviewStatus());
-//        lqw.eq(ObjectUtil.isNotEmpty(bo.getDataSource()),"b.data_source", bo.getDataSource());
-//        lqw.eq(ObjectUtil.isNotEmpty(bo.getIsSelf()),"b.is_self", bo.getIsSelf());
-//        lqw.eq(ObjectUtil.isNotEmpty(bo.getProductNo()),"b.product_no", bo.getProductNo());
-//        lqw.like(ObjectUtil.isNotEmpty(bo.getBrandName()),"br.brand_name", bo.getBrandName());
-//        // 支持分类名称模糊搜索(匹配三级分类中的任意一个)
-//        if (ObjectUtil.isNotEmpty(bo.getCategoryName())) {
-//            lqw.and(wrapper -> wrapper
-//                .like("tc.category_name", bo.getCategoryName())
-//                .or().like("mc.category_name", bo.getCategoryName())
-//                .or().like("bc.category_name", bo.getCategoryName())
-//            );
-//        }
-//        lqw.orderByAsc("b.id");
-//        int limit = pageQuery.getPageSize() + 1;
-//        lqw.last("limit "+ limit );
-//        List<ProductBaseVo> result = baseMapper.selectAllList(lqw);
-////        result.forEach(vo -> {
-////
-////        });
-//        int size = result.size();
-//        if (size > pageQuery.getPageSize()) {
-//            result.remove(result.size() - 1);
-//        }
-//        TableDataInfo<ProductBaseVo> tableDataInfo = TableDataInfo.build(result);
-//        tableDataInfo.setTotal( size);
-//        return tableDataInfo;
-//    }
-
     /**
      * 分页查询产品基础信息列表
      *
@@ -480,6 +402,7 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
             .eq(ObjectUtil.isNotEmpty(bo.getProductReviewStatus()), ProductBaseVo::getProductReviewStatus, bo.getProductReviewStatus())
             .eq(ObjectUtil.isNotEmpty(bo.getDataSource()), ProductBaseVo::getDataSource, bo.getDataSource())
             .eq(ObjectUtil.isNotEmpty(bo.getProductCategory()), ProductBaseVo::getProductCategory, bo.getProductCategory())
+            .in(ObjectUtil.isNotEmpty(bo.getIsShelfAudit()), ProductBaseVo::getProductStatus, 1,2,3)
             .orderByDesc(ProductBaseVo::getCreateTime)
             ;
         if (ObjectUtil.isNotEmpty(bo.getIds())){
@@ -501,7 +424,6 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         LambdaEsQueryWrapper<ProductBaseVo> wrapper = new LambdaEsQueryWrapper<ProductBaseVo>()
             .eq(ProductBaseVo::getProductStatus, 1)
             ;
-
         if(ObjectUtil.isNotEmpty(bo.getProductNo())){
             wrapper.eq(ProductBaseVo::getProductNo, bo.getProductNo());
         }
@@ -707,6 +629,7 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
     private void saveProductDetail(ProductBaseBo bo, Long productId) {
         ProductPhotos productPhotos= new ProductPhotos();
         productPhotos.setProductId(productId);
+        productPhotos.setImageUrl(bo.getProductImage());
         productPhotos.setProductDetailsPc(bo.getPcDetail());
         productPhotos.setProductDetailsApp(bo.getMobileDetail());
         photosMapper.insert(productPhotos);
@@ -766,11 +689,22 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
     }
 
     private void updateProductDetail(ProductBaseBo bo, Long productId) {
-        ProductPhotos productPhotos= new ProductPhotos();
-        productPhotos.setProductId(productId);
-        productPhotos.setProductDetailsPc(bo.getPcDetail());
-        productPhotos.setProductDetailsApp(bo.getMobileDetail());
-        photosMapper.update(productPhotos, new LambdaUpdateWrapper<ProductPhotos>().eq(ProductPhotos::getProductId, productId));
+        ProductPhotos productPhotos = photosMapper.selectById(productId);
+        if (productPhotos == null) {
+            productPhotos = new ProductPhotos();
+            productPhotos.setProductId(productId);
+            productPhotos.setProductDetailsPc(bo.getPcDetail());
+            productPhotos.setProductDetailsApp(bo.getMobileDetail());
+            productPhotos.setImageUrl(bo.getImageUrl());
+            photosMapper.insert(productPhotos);
+        }else{
+            productPhotos.setProductId(productId);
+            productPhotos.setProductDetailsPc(bo.getPcDetail());
+            productPhotos.setProductDetailsApp(bo.getMobileDetail());
+            productPhotos.setImageUrl(bo.getImageUrl());
+            photosMapper.update(productPhotos, new LambdaUpdateWrapper<ProductPhotos>().eq(ProductPhotos::getProductId, productId));
+        }
+
     }
 
     /**
@@ -829,6 +763,9 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         extend.setServiceGuarantee(bo.getServiceGuarantee());
         extend.setIsInstallService(bo.getFreeInstallation());
         extend.setSalesVolume(bo.getSalesVolume());
+        extend.setShelfComments(bo.getShelfComments());
+        extend.setPurchaseManagerNo(bo.getProductNature());
+        extend.setPurchaseNo(bo.getPurchasingPersonnel());
         extendMapper.insert(extend);
     }
 
@@ -894,6 +831,9 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
             if (bo.getServiceGuarantee() != null) existing.setServiceGuarantee(bo.getServiceGuarantee());
             if (bo.getFreeInstallation() != null) existing.setIsInstallService(bo.getFreeInstallation());
             if (bo.getSalesVolume() != null) existing.setSalesVolume(bo.getSalesVolume());
+            if (bo.getProductNature() != null) existing.setShelfComments(bo.getShelfComments());
+            if (bo.getProductNature() != null) existing.setPurchaseManagerNo(bo.getProductNature());
+            if (bo.getPurchasingPersonnel() != null) existing.setPurchaseNo(bo.getPurchasingPersonnel());
             extendMapper.updateById(existing);
         } else {
             // 不存在则新增
@@ -920,10 +860,12 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
             if (bo.getStandardPrice() != null) existing.setMemberPrice(bo.getStandardPrice());
             if (bo.getCertificatePrice() != null) existing.setMinSellingPrice(bo.getCertificatePrice());
             if (bo.getPurchasePrice() != null) existing.setPurchasingPrice(bo.getPurchasePrice());
+            if (bo.getTaxRate() != null) existing.setTaxRate(bo.getTaxRate());
             if (bo.getEstimatedPurchasePrice() != null) existing.setMaxPurchasePrice(bo.getEstimatedPurchasePrice());
-            if(bo.getTotalInventory() != null) existing.setTotalInventory(bo.getTotalInventory());
+            if(bo.getTotalInventory() != null) existing.setTotalInventory(bo.getVirtualInventory()+existing.getNowInventory());
             if(bo.getNowInventory() != null) existing.setNowInventory(bo.getNowInventory());
             if(bo.getVirtualInventory() != null) existing.setVirtualInventory(bo.getVirtualInventory());
+
             priceInventoryMapper.updateById(existing);
         } else {
             // 创建新记录
@@ -996,6 +938,27 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         }
     }
 
+    /**
+     * 更新库存
+     *
+     * @param bo
+     */
+    @Override
+    public Boolean updateStock(ProductBaseBo bo) {
+        ProductPriceInventory productPriceInventory = priceInventoryMapper.selectById(bo.getId());
+        // 更新库存
+        productPriceInventory.setTotalInventory(productPriceInventory.getNowInventory() + bo.getVirtualInventory());
+        productPriceInventory.setVirtualInventory(bo.getVirtualInventory());
+        boolean b = priceInventoryMapper.updateById(productPriceInventory) > 0;
+
+        esMapper.update(new LambdaEsQueryWrapper<ProductBaseVo>()
+            .eq(ProductBaseVo::getId, bo.getId())
+            .set(ProductBaseVo::getTotalInventory, productPriceInventory.getTotalInventory())
+            .set(ProductBaseVo::getVirtualInventory, productPriceInventory.getVirtualInventory())
+        );
+        return b;
+    }
+
     /**
      * 校验并批量删除产品基础信息信息
      * 性能优化:使用批量删除替代循环删除,减少数据库交互次数
@@ -1325,17 +1288,19 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
      * 商品类型改变
      *
      * @param bo
+     * @return
      */
     @Override
-    public void changeProductType(ProductBaseBo bo) {
+    public int changeProductType(ProductBaseBo bo) {
         if( ObjectUtil.isEmpty(bo.getProductCategory())){
-            return;
+            return 0;
         }
         baseMapper.update(Wrappers.lambdaUpdate(ProductBase.class)
             .set(ProductBase::getProductCategory, bo.getProductCategory())
             .eq(ProductBase::getId, bo.getId())
         );
         syncToES(bo.getId());
+        return 0;
     }
 
     /**
@@ -1438,7 +1403,6 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
                     .in(ProductBaseVo::getProductNo, productNos)
 //                    .eq(ProductBaseVo::getProductStatus, 1)
                     ;
-
                 // 检查ES索引是否存在
                 if (!esMapper.existsIndex("productbasevo")) {
                     log.warn("ES索引 [productbasevo] 不存在,降级到数据库查询");
@@ -1474,7 +1438,7 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
     public TableDataInfo<PcProductVo> getPcProductPage(PcProductBo bo, PageQuery pageQuery) {
         QueryWrapper<ProductBase> lqw = Wrappers.query(ProductBase.class);
         if(ObjectUtil.isNotEmpty( bo.getIds())){
-            lqw.in("b.id", bo.getIds());
+            lqw.in("b.id", bo.getIds().split(","));
         }
         if (ObjectUtil.isNotEmpty(bo.getBrandIds())){
             lqw.in("b.brand_id", bo.getBrandIds().split(","));
@@ -2111,5 +2075,131 @@ public class ProductBaseServiceImpl extends ServiceImpl<ProductBaseMapper, Produ
         }
         return List.of();
     }
+
+    /**
+     * 获取自营商品列表
+     *
+     * @param bo
+     * @param pageQuery
+     */
+    @Override
+    public TableDataInfo<ProductBaseVo> getSelfProductList(ProductBaseBo bo, PageQuery pageQuery) {
+        List<ProductSelfVo> productSelfVos = productSelfMapper.selectVoList(Wrappers.lambdaQuery(ProductSelf.class)
+            .eq(ObjectUtil.isNotEmpty(bo.getAuditStatus()),ProductSelf::getAuditStatus, bo.getAuditStatus())
+        );
+        if (CollUtil.isEmpty(productSelfVos)) {
+            return TableDataInfo.build();
+        }
+        LambdaEsQueryWrapper<ProductBaseVo> esQueryWrapper = new LambdaEsQueryWrapper<>();
+
+        esQueryWrapper.in(ProductBaseVo::getId, productSelfVos.stream().map(ProductSelfVo::getProductId).toList())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductNo()), ProductBaseVo::getProductNo, bo.getProductNo())
+            .like(ObjectUtil.isNotEmpty(bo.getItemName()), ProductBaseVo::getItemName, bo.getItemName())
+            .like(ObjectUtil.isNotEmpty(bo.getBrandName()), ProductBaseVo::getBrandName, bo.getBrandName())
+            .eq(bo.getBrandId() != null, ProductBaseVo::getBrandId, bo.getBrandId())
+            .eq(bo.getTopCategoryId() != null, ProductBaseVo::getTopCategoryId, bo.getTopCategoryId())
+            .eq(bo.getMediumCategoryId() != null, ProductBaseVo::getMediumCategoryId, bo.getMediumCategoryId())
+            .eq(bo.getBottomCategoryId() != null, ProductBaseVo::getBottomCategoryId, bo.getBottomCategoryId())
+            .eq(ObjectUtil.isNotEmpty(bo.getUnitId()), ProductBaseVo::getUnitId, bo.getUnitId())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductStatus()), ProductBaseVo::getProductStatus, bo.getProductStatus())
+            .eq(ObjectUtil.isNotEmpty(bo.getIsSelf()), ProductBaseVo::getIsSelf, bo.getIsSelf())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductReviewStatus()), ProductBaseVo::getProductReviewStatus, bo.getProductReviewStatus())
+            .eq(ObjectUtil.isNotEmpty(bo.getDataSource()), ProductBaseVo::getDataSource, bo.getDataSource())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductCategory()), ProductBaseVo::getProductCategory, bo.getProductCategory())
+            .orderByDesc(ProductBaseVo::getCreateTime)
+        ;
+        EsPageInfo<ProductBaseVo> esPageInfo = esMapper.pageQuery(esQueryWrapper, pageQuery.getPageNum(), pageQuery.getPageSize());
+        TableDataInfo<ProductBaseVo> tableDataInfo = TableDataInfo.build(esPageInfo.getList());
+        tableDataInfo.setTotal(esPageInfo.getTotal());
+        tableDataInfo.getRows().forEach(item -> {
+            item.setAuditStatus(productSelfVos.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditStatus());
+            item.setAuditReason(productSelfVos.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditReason());
+        });
+        return tableDataInfo;
+    }
+
+    /**
+     * 获取精品商品列表
+     *
+     * @param bo
+     * @param pageQuery
+     */
+    @Override
+    public TableDataInfo<ProductBaseVo> getGoodProductList(ProductBaseBo bo, PageQuery pageQuery) {
+        List<ProductExquisiteVo> productSelfVos = productExquisiteMapper.selectVoList(Wrappers.lambdaQuery(ProductExquisite.class)
+            .eq(ObjectUtil.isNotEmpty(bo.getAuditStatus()),ProductExquisite::getAuditStatus, bo.getAuditStatus())
+        );
+        if (CollUtil.isEmpty(productSelfVos)) {
+            return TableDataInfo.build();
+        }
+        LambdaEsQueryWrapper<ProductBaseVo> esQueryWrapper = new LambdaEsQueryWrapper<>();
+
+        esQueryWrapper.in(ProductBaseVo::getId, productSelfVos.stream().map(ProductExquisiteVo::getProductId).toList())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductNo()), ProductBaseVo::getProductNo, bo.getProductNo())
+            .like(ObjectUtil.isNotEmpty(bo.getItemName()), ProductBaseVo::getItemName, bo.getItemName())
+            .like(ObjectUtil.isNotEmpty(bo.getBrandName()), ProductBaseVo::getBrandName, bo.getBrandName())
+            .eq(bo.getBrandId() != null, ProductBaseVo::getBrandId, bo.getBrandId())
+            .eq(bo.getTopCategoryId() != null, ProductBaseVo::getTopCategoryId, bo.getTopCategoryId())
+            .eq(bo.getMediumCategoryId() != null, ProductBaseVo::getMediumCategoryId, bo.getMediumCategoryId())
+            .eq(bo.getBottomCategoryId() != null, ProductBaseVo::getBottomCategoryId, bo.getBottomCategoryId())
+            .eq(ObjectUtil.isNotEmpty(bo.getUnitId()), ProductBaseVo::getUnitId, bo.getUnitId())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductStatus()), ProductBaseVo::getProductStatus, bo.getProductStatus())
+            .eq(ObjectUtil.isNotEmpty(bo.getIsSelf()), ProductBaseVo::getIsSelf, bo.getIsSelf())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductReviewStatus()), ProductBaseVo::getProductReviewStatus, bo.getProductReviewStatus())
+            .eq(ObjectUtil.isNotEmpty(bo.getDataSource()), ProductBaseVo::getDataSource, bo.getDataSource())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductCategory()), ProductBaseVo::getProductCategory, bo.getProductCategory())
+            .orderByDesc(ProductBaseVo::getCreateTime)
+        ;
+        EsPageInfo<ProductBaseVo> esPageInfo = esMapper.pageQuery(esQueryWrapper, pageQuery.getPageNum(), pageQuery.getPageSize());
+        TableDataInfo<ProductBaseVo> tableDataInfo = TableDataInfo.build(esPageInfo.getList());
+        tableDataInfo.setTotal(esPageInfo.getTotal());
+        tableDataInfo.getRows().forEach(item -> {
+            item.setAuditStatus(productSelfVos.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditStatus());
+            item.setAuditReason(productSelfVos.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditReason());
+        });
+        return tableDataInfo;
+    }
+
+    /**
+     * 获取项目商品列表
+     *
+     * @param bo
+     * @param pageQuery
+     */
+    @Override
+    public TableDataInfo<ProductBaseVo> getItemProductList(ProductBaseBo bo, PageQuery pageQuery) {
+        List<ExternalProductDto> externalProductList = externalProductService.getExternalProductList(bo.getItemId());
+        if (CollUtil.isEmpty(externalProductList)) {
+            return TableDataInfo.build();
+        }
+        LambdaEsQueryWrapper<ProductBaseVo> esQueryWrapper = new LambdaEsQueryWrapper<>();
+        esQueryWrapper.in(ProductBaseVo::getId, externalProductList.stream().map(ExternalProductDto::getProductId).toList())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductNo()), ProductBaseVo::getProductNo, bo.getProductNo())
+            .like(ObjectUtil.isNotEmpty(bo.getItemName()), ProductBaseVo::getItemName, bo.getItemName())
+            .like(ObjectUtil.isNotEmpty(bo.getBrandName()), ProductBaseVo::getBrandName, bo.getBrandName())
+            .eq(bo.getBrandId() != null, ProductBaseVo::getBrandId, bo.getBrandId())
+            .eq(bo.getTopCategoryId() != null, ProductBaseVo::getTopCategoryId, bo.getTopCategoryId())
+            .eq(bo.getMediumCategoryId() != null, ProductBaseVo::getMediumCategoryId, bo.getMediumCategoryId())
+            .eq(bo.getBottomCategoryId() != null, ProductBaseVo::getBottomCategoryId, bo.getBottomCategoryId())
+            .eq(ObjectUtil.isNotEmpty(bo.getUnitId()), ProductBaseVo::getUnitId, bo.getUnitId())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductStatus()), ProductBaseVo::getProductStatus, bo.getProductStatus())
+            .eq(ObjectUtil.isNotEmpty(bo.getIsSelf()), ProductBaseVo::getIsSelf, bo.getIsSelf())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductReviewStatus()), ProductBaseVo::getProductReviewStatus, bo.getProductReviewStatus())
+            .eq(ObjectUtil.isNotEmpty(bo.getDataSource()), ProductBaseVo::getDataSource, bo.getDataSource())
+            .eq(ObjectUtil.isNotEmpty(bo.getProductCategory()), ProductBaseVo::getProductCategory, bo.getProductCategory())
+            .orderByDesc(ProductBaseVo::getCreateTime)
+        ;
+        EsPageInfo<ProductBaseVo> esPageInfo = esMapper.pageQuery(esQueryWrapper, pageQuery.getPageNum(), pageQuery.getPageSize());
+        TableDataInfo<ProductBaseVo> tableDataInfo = TableDataInfo.build(esPageInfo.getList());
+        tableDataInfo.setTotal(esPageInfo.getTotal());
+        tableDataInfo.getRows().forEach(item -> {
+            item.setAuditStatus(externalProductList.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditStatus());
+            item.setAuditReason(externalProductList.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditReason());
+            item.setExternalPrice(externalProductList.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getExternalPrice());
+            item.setConnectStatus(externalProductList.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getConnectStatus());
+        });
+
+        return tableDataInfo;
+    }
 }
 

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

@@ -78,6 +78,15 @@ public class ProductCategoryServiceImpl  extends ServiceImpl<ProductCategoryMapp
     public TableDataInfo<ProductCategoryVo> queryPageList(ProductCategoryBo bo, PageQuery pageQuery) {
         LambdaQueryWrapper<ProductCategory> lqw = buildQueryWrapper(bo);
         Page<ProductCategoryVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        result.getRecords().forEach(productCategory -> {
+            //通过祖籍列表查询上级分类名称
+            if (StringUtils.isNotBlank(productCategory.getAncestors())) {
+                for (String categoryId : productCategory.getAncestors().split(",")) {
+                    productCategory.setParentCategoryName(""+baseMapper.selectById(Long.valueOf(categoryId)).getCategoryName());
+                }
+
+            }
+        });
         return TableDataInfo.build(result);
     }
 

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

@@ -147,7 +147,7 @@ public class ProductPoolLinkServiceImpl implements IProductPoolLinkService {
             poolLink.setProductPrice(product.getAgreementPrice());
             poolLink.setIsPoolStatus("1"); // 1-在池中
             poolLink.setIsShow("1"); // 1-显示
-            poolLink.setProductReviewStatus("0"); // 0-待提交
+            poolLink.setProductReviewStatus("1"); // 0-待提交
 
             // 检查是否已存在
             LambdaQueryWrapper<ProductPoolLink> wrapper = Wrappers.lambdaQuery();
@@ -184,6 +184,9 @@ public class ProductPoolLinkServiceImpl implements IProductPoolLinkService {
     @Override
     public Boolean reSubmit(List<ProductPoolLinkBo> bo) {
         List<ProductPoolLink> productPoolLinks = BeanUtil.copyToList(bo, ProductPoolLink.class);
+        productPoolLinks.forEach(item -> {
+            item.setProductReviewStatus("1");
+        });
         return baseMapper.updateBatchById(productPoolLinks);
     }
 

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

@@ -96,8 +96,8 @@ public class ProductPoolServiceImpl  extends ServiceImpl<ProductPoolMapper, Prod
 
         lqw.eq(StringUtils.isNotBlank(bo.getReviewReason()), ProductPool::getReviewReason, bo.getReviewReason());
         lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), ProductPool::getPlatformCode, bo.getPlatformCode());
-        lqw.exists(StringUtils.isNotBlank(bo.getProductReviewStatus()),
-            "SELECT 1  FROM product_pool_link WHERE pool_id = product_pool.id and product_review_status = '" +bo.getProductReviewStatus() + "'");
+//        lqw.exists(StringUtils.isNotBlank(bo.getProductReviewStatus()),
+//            "SELECT 1  FROM product_pool_link WHERE pool_id = product_pool.id and product_review_status = '" +bo.getProductReviewStatus() + "'");
 
         return lqw;
     }

+ 3 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProtocolProductsServiceImpl.java

@@ -69,6 +69,7 @@ public class ProtocolProductsServiceImpl  extends ServiceImpl<ProtocolProductsMa
         //先查询协议中的商品id
         List<ProtocolProducts> protocolProducts = baseMapper.selectList(Wrappers.lambdaQuery(ProtocolProducts.class)
             .eq(ProtocolProducts::getProtocolId, bo.getProtocolId())
+            .eq(ObjectUtil.isNotEmpty(bo.getAuditStatus()),ProtocolProducts::getAuditStatus, bo.getAuditStatus())
         );
         if (protocolProducts.isEmpty()) {
             return TableDataInfo.build();
@@ -117,6 +118,8 @@ public class ProtocolProductsServiceImpl  extends ServiceImpl<ProtocolProductsMa
         }
         tableDataInfo.getRows().forEach(item -> {
             item.setAgreementPrice(protocolProducts.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAgreementPrice());
+            item.setAuditStatus(protocolProducts.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditStatus());
+            item.setAuditReason(protocolProducts.stream().filter(o -> o.getProductId().equals(item.getId())).findFirst().get().getAuditReason());
         });
         return tableDataInfo;
     }

+ 4 - 4
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductPoolMapper.xml

@@ -7,12 +7,12 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 	<select id="selectProductStatusCount" resultType="org.dromara.product.domain.vo.ProductPoolVo">
         SELECT
             pool_id AS poolId,
-            COUNT(CASE WHEN product_review_status = '0' THEN 1 END) AS waitReviewCount,
-            COUNT(CASE WHEN product_review_status = '1' THEN 1 END) AS rejectedCount,
+            COUNT(CASE WHEN product_review_status = '0' THEN 1 END) AS waitApplyCount,
+            COUNT(CASE WHEN product_review_status = '1' THEN 1 END) AS waitReviewCount,
             COUNT(CASE WHEN product_review_status = '2' THEN 1 END) AS approvedCount,
-            COUNT(CASE WHEN product_review_status = '3' THEN 1 END) AS waitApplyCount
+            COUNT(CASE WHEN product_review_status = '3' THEN 1 END) AS rejectedCount
+
         FROM product_pool_link
         WHERE pool_id = #{poolId}
-        GROUP BY product_review_status
     </select>
 </mapper>

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/ProductTaxrate.java

@@ -6,6 +6,7 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 
 import java.io.Serial;
+import java.math.BigDecimal;
 
 /**
  * 产品税率配置对象 product_taxrate
@@ -40,7 +41,7 @@ public class ProductTaxrate extends TenantEntity {
     /**
      * 税率
      */
-    private Long taxrate;
+    private BigDecimal taxrate;
 
     /**
      * 数据来源

+ 3 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/ProductTaxrateBo.java

@@ -9,6 +9,8 @@ import lombok.Data;
 import lombok.EqualsAndHashCode;
 import jakarta.validation.constraints.*;
 
+import java.math.BigDecimal;
+
 /**
  * 产品税率配置业务对象 product_taxrate
  *
@@ -38,7 +40,7 @@ public class ProductTaxrateBo extends BaseEntity {
     /**
      * 税率
      */
-    private Long taxrate;
+    private BigDecimal taxrate;
 
     /**
      * 数据来源

+ 2 - 1
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/vo/ProductTaxrateVo.java

@@ -10,6 +10,7 @@ import lombok.Data;
 
 import java.io.Serial;
 import java.io.Serializable;
+import java.math.BigDecimal;
 import java.util.Date;
 
 
@@ -46,7 +47,7 @@ public class ProductTaxrateVo implements Serializable {
      * 税率
      */
     @ExcelProperty(value = "税率")
-    private Long taxrate;
+    private BigDecimal taxrate;
 
     /**
      * 数据来源

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

@@ -437,7 +437,7 @@ public class RemoteErpSystemServiceImpl implements RemoteErpSystemService {
         productTaxrate.setDataSource("A10");
         productTaxrate.setTaxrateNo(taxCode.getTaxId());
         productTaxrate.setTaxrateName(taxCode.getTaxNm());
-        productTaxrate.setTaxrate(Math.round(taxCode.getTaxRt().doubleValue() * 100)); // 转换为整数百分比
+        productTaxrate.setTaxrate(BigDecimal.valueOf(taxCode.getTaxRt()).multiply(BigDecimal.valueOf(100))); // 转换为整数百分比
         productTaxrate.setIsShow("0"); // 默认显示
 
         return productTaxrateService.saveOrUpdate(productTaxrate);