Kaynağa Gözat

zl-1-12-后端

林小张 3 ay önce
ebeveyn
işleme
bd9a666f4e
47 değiştirilmiş dosya ile 1269 ekleme ve 65 silme
  1. 5 4
      pom.xml
  2. 10 1
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteCustomerService.java
  3. 25 0
      ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/CustomerApiVo.java
  4. 31 0
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteProductProgramService.java
  5. 28 0
      ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/domain/ProductProgramApiVo.java
  6. 8 0
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java
  7. 0 2
      ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/domain/vo/RemoteDeptVo.java
  8. 2 0
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  9. 3 1
      ruoyi-modules/ruoyi-customer/pom.xml
  10. 2 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/RuoyiCustomerApplication.java
  11. 106 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerProgramController.java
  12. 57 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerProgram.java
  13. 53 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerProgramBo.java
  14. 6 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptVo.java
  15. 3 3
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerListVo.java
  16. 81 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerProgramVo.java
  17. 27 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteCustomerServiceImpl.java
  18. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerBusinessInfoMapper.java
  19. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerContactMapper.java
  20. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerContractMapper.java
  21. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerInvoiceInfoMapper.java
  22. 15 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerProgramMapper.java
  23. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerSalesInfoMapper.java
  24. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerShippingAddressMapper.java
  25. 70 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerProgramService.java
  26. 49 23
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerDeptServiceImpl.java
  27. 7 7
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerInfoServiceImpl.java
  28. 191 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerProgramServiceImpl.java
  29. 1 1
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerInfoMapper.xml
  30. 7 0
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerProgramMapper.xml
  31. 5 0
      ruoyi-modules/ruoyi-product/pom.xml
  32. 2 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/RuoyiProductApplication.java
  33. 8 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBaseController.java
  34. 4 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/bo/ProductBlacklistBo.java
  35. 115 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBaseSimpleVo.java
  36. 39 6
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBlacklistVo.java
  37. 57 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteProductProgramServiceImpl.java
  38. 10 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ProductBaseMapper.java
  39. 8 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ProductBlacklistMapper.java
  40. 10 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java
  41. 14 0
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBaseServiceImpl.java
  42. 33 7
      ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBlacklistServiceImpl.java
  43. 52 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBaseMapper.xml
  44. 41 0
      ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBlacklistMapper.xml
  45. 4 4
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java
  46. 7 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java
  47. 67 0
      script/sql/global_setting_menu.sql

+ 5 - 4
pom.xml

@@ -78,20 +78,21 @@
                 <nacos.password>nacos</nacos.password>
                 <logstash.address>127.0.0.1:4560</logstash.address>
             </properties>
+
         </profile>
         <profile>
-            <id>hrx</id>
+            <id>zl</id>
             <properties>
                 <!-- 环境标识,需要与配置文件的名称相对应 -->
-                <profiles.active>5346d34f-9daf-4259-bc2f-5219f814987f</profiles.active>
-                <nacos.server>127.0.0.1:8848</nacos.server>
+                <profiles.active>zl</profiles.active>
+                <nacos.server>169.254.38.213:8848</nacos.server>
                 <nacos.discovery.group>DEFAULT_GROUP</nacos.discovery.group>
                 <nacos.config.group>DEFAULT_GROUP</nacos.config.group>
                 <nacos.username>nacos</nacos.username>
                 <nacos.password>nacos</nacos.password>
                 <logstash.address>127.0.0.1:4560</logstash.address>
             </properties>
-            <activation>
+             <activation>
                 <!-- 默认环境 -->
                 <activeByDefault>true</activeByDefault>
             </activation>

+ 10 - 1
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/RemoteCustomerService.java

@@ -1,10 +1,19 @@
 package org.dromara.customer.api;
 
+import org.dromara.customer.api.domain.CustomerApiVo;
+
 import java.util.Map;
 import java.util.Set;
 
 public interface RemoteCustomerService {
 
-    /*根据ids查询客户名称*/
+    /**
+     * 根据ids查询客户名称
+     */
     Map<Long, String> selectCustomerNameByIds(Set<Long> ids);
+
+    /**
+     * 根据ids查询客户信息(编号+名称)
+     */
+    Map<Long, CustomerApiVo> selectCustomerByIds(Set<Long> ids);
 }

+ 25 - 0
ruoyi-api/ruoyi-api-customer/src/main/java/org/dromara/customer/api/domain/CustomerApiVo.java

@@ -0,0 +1,25 @@
+package org.dromara.customer.api.domain;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 客户API视图对象
+ */
+@Data
+public class CustomerApiVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /** 客户ID */
+    private Long id;
+
+    /** 客户编号 */
+    private String customerNo;
+
+    /** 客户名称 */
+    private String customerName;
+}

+ 31 - 0
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/RemoteProductProgramService.java

@@ -0,0 +1,31 @@
+package org.dromara.product.api;
+
+import org.dromara.product.api.domain.ProductProgramApiVo;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * 产品方案远程服务接口
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+public interface RemoteProductProgramService {
+
+    /**
+     * 根据ID批量查询方案信息
+     *
+     * @param ids 方案ID集合
+     * @return Map<ID, 方案信息>
+     */
+    Map<Long, ProductProgramApiVo> selectProgramByIds(Set<Long> ids);
+
+    /**
+     * 查询所有方案列表(用于下拉选择)
+     *
+     * @return 方案列表
+     */
+    List<ProductProgramApiVo> selectAllProgramList();
+}

+ 28 - 0
ruoyi-api/ruoyi-api-product/src/main/java/org/dromara/product/api/domain/ProductProgramApiVo.java

@@ -0,0 +1,28 @@
+package org.dromara.product.api.domain;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+/**
+ * 产品方案API视图对象
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+@Data
+public class ProductProgramApiVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /** 方案ID */
+    private Long id;
+
+    /** 方案编号 */
+    private String programNo;
+
+    /** 方案标题 */
+    private String title;
+}

+ 8 - 0
ruoyi-api/ruoyi-api-system/src/main/java/org/dromara/system/api/RemoteDeptService.java

@@ -43,6 +43,14 @@ public interface RemoteDeptService {
 
     RemoteDeptVo insertDept(RemoteDeptVo vo);
 
+    /**
+     * 更新部门信息
+     *
+     * @param vo 部门信息
+     * @return 更新后的部门信息
+     */
+    RemoteDeptVo updateDept(RemoteDeptVo vo);
+
     List<RemoteDeptVo> selectDeptByIds(List<Long> deptIds);
 
     /**

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

@@ -34,8 +34,6 @@ public class RemoteDeptVo implements Serializable {
      */
     private String deptName;
 
-    private Long customerId;
-
     private String status;
 
     private Integer orderNum;

+ 2 - 0
ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java

@@ -61,6 +61,8 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "invoice_type",
         "customer_info",
         "customer_dept",
+        "customer_contact",
+        "customer_contract",
         "com_bank",
         "settlement_level",
         "settlement_method",

+ 3 - 1
ruoyi-modules/ruoyi-customer/pom.xml

@@ -112,9 +112,11 @@
             <groupId>org.dromara</groupId>
             <artifactId>ruoyi-api-customer</artifactId>
         </dependency>
+
+        <!-- RuoYi Api Product -->
         <dependency>
             <groupId>org.dromara</groupId>
-            <artifactId>ruoyi-api-customer</artifactId>
+            <artifactId>ruoyi-api-product</artifactId>
         </dependency>
 
     </dependencies>

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

@@ -1,9 +1,11 @@
 package org.dromara.customer;
 
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
 
+@EnableDubbo
 @SpringBootApplication
 public class RuoyiCustomerApplication {
 

+ 106 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerProgramController.java

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

+ 57 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/CustomerProgram.java

@@ -0,0 +1,57 @@
+package org.dromara.customer.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 客户专属方案关联对象 customer_program
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("customer_program")
+public class CustomerProgram extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID(关联customer_info.id)
+     */
+    private Long customerId;
+
+    /**
+     * 专属方案ID(关联product_program.id)
+     */
+    private Long programId;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    private String status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 53 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerProgramBo.java

@@ -0,0 +1,53 @@
+package org.dromara.customer.domain.bo;
+
+import org.dromara.customer.domain.CustomerProgram;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+
+/**
+ * 客户专属方案关联业务对象 customer_program
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = CustomerProgram.class, reverseConvertGenerate = false)
+public class CustomerProgramBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID(关联customer_info.id)
+     */
+//    @NotNull(message = "客户ID(关联customer_info.id)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long customerId;
+
+    /**
+     * 专属方案ID(关联product_program.id)
+     */
+//    @NotNull(message = "专属方案ID(关联product_program.id)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private Long programId;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+//    @NotBlank(message = "状态(0正常 1停用)不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String status;
+
+    /**
+     * 备注
+     */
+//    @NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String remark;
+
+
+}

+ 6 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerDeptVo.java

@@ -149,5 +149,11 @@ public class CustomerDeptVo implements Serializable {
     @ExcelProperty(value = "备注")
     private String remark;
 
+    /**
+     * 创建时间
+     */
+    @ExcelProperty(value = "创建时间")
+    private Date createTime;
+
 
 }

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

@@ -35,11 +35,11 @@ public class CustomerListVo implements Serializable {
     /** 信用额度 */
     private BigDecimal creditAmount;
 
-    /** 信用等级ID */
-    private Long customerLevelId;
+    /** 信用等级ID(关联credit_level表) */
+    private Long creditLevelId;
 
     /** 信用等级名称 */
-    private String customerLevelName;
+    private String creditLevelName;
 
     /** 应收账款 */
     private BigDecimal accountsReceivable;

+ 81 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/CustomerProgramVo.java

@@ -0,0 +1,81 @@
+package org.dromara.customer.domain.vo;
+
+import org.dromara.customer.domain.CustomerProgram;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+
+
+
+/**
+ * 客户专属方案关联视图对象 customer_program
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = CustomerProgram.class)
+public class CustomerProgramVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID(关联customer_info.id)
+     */
+    @ExcelProperty(value = "客户ID")
+    private Long customerId;
+
+    /**
+     * 客户编号(远程查询回填)
+     */
+    @ExcelProperty(value = "客户编号")
+    private String customerNo;
+
+    /**
+     * 专属方案ID(关联product_program.id)
+     */
+    @ExcelProperty(value = "专属方案ID")
+    private Long programId;
+
+    /**
+     * 方案编号(远程查询回填)
+     */
+    @ExcelProperty(value = "方案编号")
+    private String programNo;
+
+    /**
+     * 方案名称(远程查询回填)
+     */
+    @ExcelProperty(value = "方案名称")
+    private String programName;
+
+    /**
+     * 状态(0正常 1停用)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=正常,1=停用")
+    private String status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 27 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/dubbo/RemoteCustomerServiceImpl.java

@@ -1,14 +1,21 @@
 package org.dromara.customer.dubbo;
 
+import cn.hutool.core.collection.CollUtil;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
 import org.apache.dubbo.config.annotation.DubboService;
 import org.dromara.customer.api.RemoteCustomerService;
+import org.dromara.customer.api.domain.CustomerApiVo;
+import org.dromara.customer.domain.CustomerInfo;
+import org.dromara.customer.mapper.CustomerInfoMapper;
 import org.dromara.customer.service.ICustomerInfoService;
 import org.springframework.stereotype.Service;
 
+import java.util.Collections;
+import java.util.List;
 import java.util.Map;
 import java.util.Set;
+import java.util.stream.Collectors;
 
 @Slf4j
 @Service
@@ -17,9 +24,29 @@ import java.util.Set;
 public class RemoteCustomerServiceImpl implements RemoteCustomerService {
 
     private final ICustomerInfoService customerInfoService;
+    private final CustomerInfoMapper customerInfoMapper;
 
     @Override
     public Map<Long, String> selectCustomerNameByIds(Set<Long> ids) {
         return customerInfoService.selectCustomerNameByIds(ids);
     }
+
+    @Override
+    public Map<Long, CustomerApiVo> selectCustomerByIds(Set<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyMap();
+        }
+        List<CustomerInfo> list = customerInfoMapper.selectBatchIds(ids);
+        return list.stream().collect(Collectors.toMap(
+            CustomerInfo::getId,
+            c -> {
+                CustomerApiVo vo = new CustomerApiVo();
+                vo.setId(c.getId());
+                vo.setCustomerNo(c.getCustomerNo());
+                vo.setCustomerName(c.getCustomerName() != null ? c.getCustomerName() : c.getBusinessCustomerName());
+                return vo;
+            },
+            (v1, v2) -> v1
+        ));
+    }
 }

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerBusinessInfoMapper.java

@@ -1,6 +1,6 @@
 package org.dromara.customer.mapper;
 
-import org.apache.dubbo.remoting.http12.rest.Param;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.customer.domain.CustomerBusinessInfo;
 import org.dromara.customer.domain.vo.CustomerBusinessInfoVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerContactMapper.java

@@ -1,6 +1,6 @@
 package org.dromara.customer.mapper;
 
-import org.apache.dubbo.remoting.http12.rest.Param;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.customer.domain.CustomerContact;
 import org.dromara.customer.domain.CustomerInvoiceInfo;
 import org.dromara.customer.domain.vo.CustomerContactVo;

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerContractMapper.java

@@ -1,6 +1,6 @@
 package org.dromara.customer.mapper;
 
-import org.apache.dubbo.remoting.http12.rest.Param;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.customer.domain.CustomerContract;
 import org.dromara.customer.domain.vo.CustomerContractVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerInvoiceInfoMapper.java

@@ -1,6 +1,6 @@
 package org.dromara.customer.mapper;
 
-import org.apache.dubbo.remoting.http12.rest.Param;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 import org.dromara.customer.domain.CustomerInvoiceInfo;
 import org.dromara.customer.domain.vo.CustomerInvoiceInfoVo;

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

@@ -0,0 +1,15 @@
+package org.dromara.customer.mapper;
+
+import org.dromara.customer.domain.CustomerProgram;
+import org.dromara.customer.domain.vo.CustomerProgramVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 客户专属方案关联Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+public interface CustomerProgramMapper extends BaseMapperPlus<CustomerProgram, CustomerProgramVo> {
+
+}

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerSalesInfoMapper.java

@@ -1,6 +1,6 @@
 package org.dromara.customer.mapper;
 
-import org.apache.dubbo.remoting.http12.rest.Param;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.customer.domain.CustomerSalesInfo;
 import org.dromara.customer.domain.vo.CustomerBusinessInfoVo;
 import org.dromara.customer.domain.vo.CustomerSalesInfoVo;

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/mapper/CustomerShippingAddressMapper.java

@@ -1,6 +1,6 @@
 package org.dromara.customer.mapper;
 
-import org.apache.dubbo.remoting.http12.rest.Param;
+import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.annotations.Update;
 import org.dromara.customer.domain.CustomerShippingAddress;
 import org.dromara.customer.domain.vo.CustomerShippingAddressVo;

+ 70 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerProgramService.java

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

+ 49 - 23
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerDeptServiceImpl.java

@@ -68,7 +68,37 @@ public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, Cus
     @Override
     public List<CustomerDeptVo> queryList(CustomerDeptBo bo) {
         LambdaQueryWrapper<CustomerDept> lqw = buildQueryWrapper(bo);
-        return baseMapper.selectVoList(lqw);
+        List<CustomerDeptVo> list = baseMapper.selectVoList(lqw);
+        
+        if (CollUtil.isEmpty(list)) {
+            return list;
+        }
+        
+        // 关联查询 sys_dept 获取部门名称等信息
+        List<Long> deptIds = list.stream()
+            .map(CustomerDeptVo::getDeptId)
+            .filter(id -> id != null)
+            .collect(Collectors.toList());
+        
+        if (CollUtil.isEmpty(deptIds)) {
+            return list;
+        }
+        
+        List<RemoteDeptVo> sysDepts = remoteDeptService.selectDeptByIds(deptIds);
+        Map<Long, RemoteDeptVo> deptMap = sysDepts.stream()
+            .collect(Collectors.toMap(RemoteDeptVo::getDeptId, d -> d, (e, r) -> e));
+        
+        // 补充部门名称等信息
+        for (CustomerDeptVo vo : list) {
+            RemoteDeptVo sysDept = deptMap.get(vo.getDeptId());
+            if (sysDept != null) {
+                vo.setDeptName(sysDept.getDeptName());
+                vo.setParentId(sysDept.getParentId());
+                vo.setStatus(sysDept.getStatus());
+            }
+        }
+        
+        return list;
     }
 
     @Override
@@ -138,7 +168,7 @@ public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, Cus
         lqw.eq(StringUtils.isNotBlank(bo.getDeptManage()), CustomerDept::getDeptManage, bo.getDeptManage());
         lqw.eq(StringUtils.isNotBlank(bo.getIsLimit()), CustomerDept::getIsLimit, bo.getIsLimit());
         lqw.eq(StringUtils.isNotBlank(bo.getSelectYear()), CustomerDept::getSelectYear, bo.getSelectYear());
-        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), CustomerDept::getPlatformCode, bo.getPlatformCode());
+        // lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), CustomerDept::getPlatformCode, bo.getPlatformCode());
         return lqw;
     }
 
@@ -189,33 +219,29 @@ public class CustomerDeptServiceImpl extends ServiceImpl<CustomerDeptMapper, Cus
 
     @Override
     public Boolean updateByBo(CustomerDeptBo bo) {
-
         if (bo == null || bo.getDeptId() == null || bo.getDeptId() <= 0) {
             return false;
         }
-        RemoteDeptVo remoteDeptVo = remoteDeptService.selectDeptById(bo.getDeptId());
-        if (remoteDeptVo == null) {
-            return false;
-        }
-
-        MapstructUtils.convert(bo, CustomerInfo.class);
-
-
-        // 1. 更新主表
-        CustomerInfo entity = MapstructUtils.convert(bo, CustomerInfo.class);
-//        boolean mainUpdated = baseMapper.updateById(entity) > 0;
-//        if (!mainUpdated) {
-//            return false;
-//        }
-//
-//        Long customerId = bo.getId();
-
-
-        return true;
+        
+        // 更新 customer_dept 表(业务扩展字段)
+        // 注意:部门名称、上级部门等基础信息存在 sys_dept 表,暂不支持修改
+        CustomerDept dept = new CustomerDept();
+        dept.setDeptId(bo.getDeptId());
+        dept.setCustomerId(bo.getCustomerId());
+        dept.setYearlyBudget(bo.getYearlyBudget());
+        dept.setMonthLimit(bo.getMonthLimit());
+        dept.setUsedBudget(bo.getUsedBudget());
+        dept.setBindStatus(bo.getBindStatus());
+        dept.setBindAddress(bo.getBindAddress());
+        
+        return baseMapper.updateById(dept) > 0;
     }
 
     @Override
     public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
-        return null;
+        if (CollUtil.isEmpty(ids)) {
+            return false;
+        }
+        return baseMapper.deleteBatchIds(ids) > 0;
     }
 }

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

@@ -414,10 +414,10 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
      */
     @Override
     public TableDataInfo<CustomerListVo> queryCustomerListPage(CustomerListBo bo, PageQuery pageQuery) {
-        // 设置平台标识
-        if (StringUtils.isBlank(bo.getPlatformCode())) {
-            bo.setPlatformCode(PlatformContext.getPlatform());
-        }
+        // 设置平台标识(暂时注释掉)
+        // if (StringUtils.isBlank(bo.getPlatformCode())) {
+        //     bo.setPlatformCode(PlatformContext.getPlatform());
+        // }
         Page<CustomerListVo> page = baseMapper.selectCustomerListPage(pageQuery.build(), bo);
 
         // 补充业务员名称和信用等级名称
@@ -429,9 +429,9 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
                 .filter(Objects::nonNull)
                 .collect(Collectors.toSet());
 
-            // 收集信用等级ID
+            // 收集信用等级ID(从 credit_management_id 字段)
             Set<Long> creditLevelIds = records.stream()
-                .map(CustomerListVo::getCustomerLevelId)
+                .map(CustomerListVo::getCreditLevelId)
                 .filter(Objects::nonNull)
                 .collect(Collectors.toSet());
 
@@ -444,7 +444,7 @@ public class CustomerInfoServiceImpl extends ServiceImpl<CustomerInfoMapper, Cus
             // 批量查询信用等级名称
             if (!creditLevelIds.isEmpty()) {
                 Map<Long, String> creditLevelMap = remoteCreditLevelService.selectCreditLevelNameByIds(creditLevelIds);
-                records.forEach(vo -> vo.setCustomerLevelName(creditLevelMap.get(vo.getCustomerLevelId())));
+                records.forEach(vo -> vo.setCreditLevelName(creditLevelMap.get(vo.getCreditLevelId())));
             }
         }
 

+ 191 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerProgramServiceImpl.java

@@ -0,0 +1,191 @@
+package org.dromara.customer.service.impl;
+
+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;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.customer.domain.CustomerInfo;
+import org.dromara.customer.mapper.CustomerInfoMapper;
+import org.dromara.product.api.RemoteProductProgramService;
+import org.dromara.product.api.domain.ProductProgramApiVo;
+import org.springframework.stereotype.Service;
+import org.dromara.customer.domain.bo.CustomerProgramBo;
+import org.dromara.customer.domain.vo.CustomerProgramVo;
+import org.dromara.customer.domain.CustomerProgram;
+import org.dromara.customer.mapper.CustomerProgramMapper;
+import org.dromara.customer.service.ICustomerProgramService;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 客户专属方案关联Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class CustomerProgramServiceImpl extends ServiceImpl<CustomerProgramMapper, CustomerProgram> implements ICustomerProgramService {
+
+    private final CustomerProgramMapper baseMapper;
+    private final CustomerInfoMapper customerInfoMapper;
+
+    @DubboReference
+    private RemoteProductProgramService remoteProductProgramService;
+
+    /**
+     * 查询客户专属方案关联
+     *
+     * @param id 主键
+     * @return 客户专属方案关联
+     */
+    @Override
+    public CustomerProgramVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询客户专属方案关联列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 客户专属方案关联分页列表
+     */
+    @Override
+    public TableDataInfo<CustomerProgramVo> queryPageList(CustomerProgramBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<CustomerProgram> lqw = buildQueryWrapper(bo);
+        Page<CustomerProgramVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+
+        // 补充客户编号和方案信息
+        List<CustomerProgramVo> records = result.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            // 收集客户ID
+            Set<Long> customerIds = records.stream()
+                .map(CustomerProgramVo::getCustomerId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            // 收集方案ID
+            Set<Long> programIds = records.stream()
+                .map(CustomerProgramVo::getProgramId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            // 查询客户编号
+            Map<Long, String> customerNoMap = Collections.emptyMap();
+            if (!customerIds.isEmpty()) {
+                List<CustomerInfo> customerList = customerInfoMapper.selectBatchIds(customerIds);
+                customerNoMap = customerList.stream().collect(Collectors.toMap(
+                    CustomerInfo::getId,
+                    CustomerInfo::getCustomerNo,
+                    (v1, v2) -> v1
+                ));
+            }
+
+            // 远程查询方案信息
+            Map<Long, ProductProgramApiVo> programMap = Collections.emptyMap();
+            if (!programIds.isEmpty()) {
+                programMap = remoteProductProgramService.selectProgramByIds(programIds);
+            }
+
+            // 回填数据
+            final Map<Long, String> finalCustomerNoMap = customerNoMap;
+            final Map<Long, ProductProgramApiVo> finalProgramMap = programMap;
+            records.forEach(vo -> {
+                vo.setCustomerNo(finalCustomerNoMap.get(vo.getCustomerId()));
+                ProductProgramApiVo programVo = finalProgramMap.get(vo.getProgramId());
+                if (programVo != null) {
+                    vo.setProgramNo(programVo.getProgramNo());
+                    vo.setProgramName(programVo.getTitle());
+                }
+            });
+        }
+
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的客户专属方案关联列表
+     *
+     * @param bo 查询条件
+     * @return 客户专属方案关联列表
+     */
+    @Override
+    public List<CustomerProgramVo> queryList(CustomerProgramBo bo) {
+        LambdaQueryWrapper<CustomerProgram> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<CustomerProgram> buildQueryWrapper(CustomerProgramBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<CustomerProgram> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(CustomerProgram::getId);
+        lqw.eq(bo.getCustomerId() != null, CustomerProgram::getCustomerId, bo.getCustomerId());
+        lqw.eq(bo.getProgramId() != null, CustomerProgram::getProgramId, bo.getProgramId());
+        lqw.eq(StringUtils.isNotBlank(bo.getStatus()), CustomerProgram::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), CustomerProgram::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增客户专属方案关联
+     *
+     * @param bo 客户专属方案关联
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(CustomerProgramBo bo) {
+        CustomerProgram add = MapstructUtils.convert(bo, CustomerProgram.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改客户专属方案关联
+     *
+     * @param bo 客户专属方案关联
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(CustomerProgramBo bo) {
+        CustomerProgram update = MapstructUtils.convert(bo, CustomerProgram.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(CustomerProgram entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除客户专属方案关联信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 1 - 1
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerInfoMapper.xml

@@ -59,7 +59,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             ci.industry_category_id AS industryCategoryId,
             ic.industry_category_name AS industryName,
             csi.credit_amount AS creditAmount,
-            ci.customer_level_id AS customerLevelId,
+            csi.credit_management_id AS creditLevelId,
             csi.accounts_receivable AS accountsReceivable,
             csi.sales_person_id AS salesPersonId,
             ci.status

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

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

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

@@ -109,6 +109,11 @@
             <artifactId>ruoyi-api-product</artifactId>
         </dependency>
 
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
+
 
     </dependencies>
 

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

@@ -1,11 +1,13 @@
 package org.dromara.product;
 
+import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
 import org.springframework.boot.SpringApplication;
 import org.springframework.boot.autoconfigure.SpringBootApplication;
 import org.springframework.boot.context.metrics.buffering.BufferingApplicationStartup;
 
 import java.math.BigDecimal;
 
+@EnableDubbo
 @SpringBootApplication
 public class RuoyiProductApplication {
 

+ 8 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/controller/ProductBaseController.java

@@ -200,4 +200,12 @@ public class ProductBaseController extends BaseController {
         return productBaseService.queryProductOperationPageList(bo, pageQuery);
     }
 
+    /**
+     * 查询商品简化列表(用于选择弹窗,字段精简)
+     */
+    @GetMapping("/simpleList")
+    public TableDataInfo<ProductBaseSimpleVo> simpleList(ProductBaseBo bo, PageQuery pageQuery) {
+        return productBaseService.querySimplePageList(bo, pageQuery);
+    }
+
 }

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

@@ -48,5 +48,9 @@ public class ProductBlacklistBo extends BaseEntity {
     //@NotBlank(message = "备注不能为空", groups = { AddGroup.class, EditGroup.class })
     private String remark;
 
+    /**
+     * 黑名单类型:product=商品黑名单,category=分类黑名单
+     */
+    private String blacklistType;
 
 }

+ 115 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBaseSimpleVo.java

@@ -0,0 +1,115 @@
+package org.dromara.product.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.math.BigDecimal;
+
+/**
+ * 产品基础信息简化视图对象(用于选择列表)
+ *
+ * @author LionLi
+ * @date 2025-01-09
+ */
+@Data
+public class ProductBaseSimpleVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 产品编号
+     */
+    private String productNo;
+
+    /**
+     * 产品名称
+     */
+    private String itemName;
+
+    /**
+     * 产品图片
+     */
+    private String productImage;
+
+    /**
+     * 市场价
+     */
+    private BigDecimal marketPrice;
+
+    /**
+     * 会员价格
+     */
+    private BigDecimal memberPrice;
+
+    /**
+     * 规格型号
+     */
+    private String specification;
+
+    /**
+     * 顶级分类id
+     */
+    private Long topCategoryId;
+
+    /**
+     * 顶级分类名称
+     */
+    private String topCategoryName;
+
+    /**
+     * 中级分类id
+     */
+    private Long mediumCategoryId;
+
+    /**
+     * 中级分类名称
+     */
+    private String mediumCategoryName;
+
+    /**
+     * 底层分类id
+     */
+    private Long bottomCategoryId;
+
+    /**
+     * 底层分类名称
+     */
+    private String bottomCategoryName;
+
+    /**
+     * 首页推荐:1=推荐,0=不推荐
+     */
+    private String homeRecommended;
+
+    /**
+     * 分类推荐:1=推荐,0=不推荐
+     */
+    private String categoryRecommendation;
+
+    /**
+     * 购物车推荐:1=推荐,0=不推荐
+     */
+    private String cartRecommendation;
+
+    /**
+     * 推荐产品顺序
+     */
+    private Long recommendedProductOrder;
+
+    /**
+     * 是否热门:1=是,0=否
+     */
+    private String isPopular;
+
+    /**
+     * 商品状态:1=上架,0=下架
+     */
+    private String productStatus;
+}

+ 39 - 6
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/domain/vo/ProductBlacklistVo.java

@@ -37,24 +37,57 @@ public class ProductBlacklistVo implements Serializable {
     /**
      * 客户id(可为空,表示全局黑名单)
      */
-    @ExcelProperty(value = "客户id", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "可=为空,表示全局黑名单")
+    @ExcelProperty(value = "客户ID")
     private Long customerId;
 
+    /**
+     * 客户编号
+     */
+    @ExcelProperty(value = "客户编号")
+    private String customerNo;
+
+    /**
+     * 客户名称
+     */
+    @ExcelProperty(value = "客户名称")
+    private String customerName;
+
     /**
      * 产品id(可为空,表示该客户对整个分类禁用)
      */
-    @ExcelProperty(value = "产品id", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "可=为空,表示该客户对整个分类禁用")
+    @ExcelProperty(value = "商品ID")
     private Long productId;
 
+    /**
+     * 商品编号
+     */
+    @ExcelProperty(value = "商品编号")
+    private String productNo;
+
+    /**
+     * 商品名称
+     */
+    @ExcelProperty(value = "商品名称")
+    private String productName;
+
     /**
      * 产品分类id(必填)
      */
-    @ExcelProperty(value = "产品分类id", converter = ExcelDictConvert.class)
-    @ExcelDictFormat(readConverterExp = "必=填")
+    @ExcelProperty(value = "分类ID")
     private Long productCategoryId;
 
+    /**
+     * 分类编号
+     */
+    @ExcelProperty(value = "分类编号")
+    private String categoryNo;
+
+    /**
+     * 分类名称
+     */
+    @ExcelProperty(value = "分类名称")
+    private String categoryName;
+
     /**
      * 备注
      */

+ 57 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/dubbo/RemoteProductProgramServiceImpl.java

@@ -0,0 +1,57 @@
+package org.dromara.product.dubbo;
+
+import cn.hutool.core.collection.CollUtil;
+import lombok.RequiredArgsConstructor;
+import org.apache.dubbo.config.annotation.DubboService;
+import org.dromara.product.api.RemoteProductProgramService;
+import org.dromara.product.api.domain.ProductProgramApiVo;
+import org.dromara.product.domain.ProductProgram;
+import org.dromara.product.mapper.ProductProgramMapper;
+import org.springframework.stereotype.Service;
+
+import java.util.*;
+import java.util.stream.Collectors;
+
+/**
+ * 产品方案远程服务实现
+ *
+ * @author LionLi
+ * @date 2026-01-09
+ */
+@RequiredArgsConstructor
+@Service
+@DubboService
+public class RemoteProductProgramServiceImpl implements RemoteProductProgramService {
+
+    private final ProductProgramMapper productProgramMapper;
+
+    @Override
+    public Map<Long, ProductProgramApiVo> selectProgramByIds(Set<Long> ids) {
+        if (CollUtil.isEmpty(ids)) {
+            return Collections.emptyMap();
+        }
+        List<ProductProgram> list = productProgramMapper.selectBatchIds(ids);
+        return list.stream().collect(Collectors.toMap(
+            ProductProgram::getId,
+            this::convertToApiVo,
+            (v1, v2) -> v1
+        ));
+    }
+
+    @Override
+    public List<ProductProgramApiVo> selectAllProgramList() {
+        List<ProductProgram> list = productProgramMapper.selectList(null);
+        if (CollUtil.isEmpty(list)) {
+            return Collections.emptyList();
+        }
+        return list.stream().map(this::convertToApiVo).collect(Collectors.toList());
+    }
+
+    private ProductProgramApiVo convertToApiVo(ProductProgram program) {
+        ProductProgramApiVo vo = new ProductProgramApiVo();
+        vo.setId(program.getId());
+        vo.setProgramNo(program.getProgramNo());
+        vo.setTitle(program.getTitle());
+        return vo;
+    }
+}

+ 10 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ProductBaseMapper.java

@@ -6,6 +6,7 @@ import org.dromara.product.domain.ProductBase;
 import org.dromara.product.domain.bo.ProductBaseBo;
 import org.dromara.product.domain.bo.SiteProductBo;
 import org.dromara.product.domain.vo.ProductBaseVo;
+import org.dromara.product.domain.vo.ProductBaseSimpleVo;
 import org.dromara.product.domain.vo.ProductOperationVo;
 import org.dromara.product.domain.vo.RecommendProductVo;
 import org.dromara.product.domain.vo.SiteProductVo;
@@ -45,4 +46,13 @@ public interface ProductBaseMapper extends BaseMapperPlus<ProductBase, ProductBa
      * @return 商品运营分页列表
      */
     Page<ProductOperationVo> selectProductOperationPage(@Param("page") Page<ProductOperationVo> page, @Param("bo") ProductBaseBo bo);
+
+    /**
+     * 分页查询商品简化列表(用于选择弹窗)
+     *
+     * @param page 分页参数
+     * @param bo   查询条件
+     * @return 商品简化分页列表
+     */
+    Page<ProductBaseSimpleVo> selectSimplePage(@Param("page") Page<ProductBaseSimpleVo> page, @Param("bo") ProductBaseBo bo);
 }

+ 8 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/mapper/ProductBlacklistMapper.java

@@ -1,6 +1,9 @@
 package org.dromara.product.mapper;
 
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import org.apache.ibatis.annotations.Param;
 import org.dromara.product.domain.ProductBlacklist;
+import org.dromara.product.domain.bo.ProductBlacklistBo;
 import org.dromara.product.domain.vo.ProductBlacklistVo;
 import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
 
@@ -12,4 +15,9 @@ import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
  */
 public interface ProductBlacklistMapper extends BaseMapperPlus<ProductBlacklist, ProductBlacklistVo> {
 
+    /**
+     * 分页查询黑名单列表(关联商品和分类)
+     */
+    Page<ProductBlacklistVo> selectBlacklistPage(@Param("page") Page<ProductBlacklistVo> page,
+                                                  @Param("bo") ProductBlacklistBo bo);
 }

+ 10 - 0
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/IProductBaseService.java

@@ -3,6 +3,7 @@ package org.dromara.product.service;
 import com.baomidou.mybatisplus.extension.service.IService;
 import org.dromara.product.domain.ProductBase;
 import org.dromara.product.domain.vo.ProductBaseVo;
+import org.dromara.product.domain.vo.ProductBaseSimpleVo;
 import org.dromara.product.domain.vo.ProductOperationVo;
 import org.dromara.product.domain.vo.RecommendProductVo;
 import org.dromara.product.domain.vo.SiteProductVo;
@@ -105,4 +106,13 @@ public interface IProductBaseService extends IService<ProductBase>{
      * @return 商品运营分页列表
      */
     TableDataInfo<ProductOperationVo> queryProductOperationPageList(ProductBaseBo bo, PageQuery pageQuery);
+
+    /**
+     * 分页查询商品简化列表(用于选择弹窗)
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 商品简化分页列表
+     */
+    TableDataInfo<ProductBaseSimpleVo> querySimplePageList(ProductBaseBo bo, PageQuery pageQuery);
 }

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

@@ -20,6 +20,7 @@ import org.springframework.transaction.annotation.Transactional;
 import org.dromara.product.domain.bo.ProductBaseBo;
 import org.dromara.product.domain.bo.SiteProductBo;
 import org.dromara.product.domain.vo.ProductBaseVo;
+import org.dromara.product.domain.vo.ProductBaseSimpleVo;
 import org.dromara.product.domain.vo.ProductOperationVo;
 import org.dromara.product.domain.vo.RecommendProductVo;
 import org.dromara.product.domain.vo.SiteProductVo;
@@ -754,4 +755,17 @@ public class ProductBaseServiceImpl  extends ServiceImpl<ProductBaseMapper, Prod
         Page<ProductOperationVo> page = baseMapper.selectProductOperationPage(pageQuery.build(), bo);
         return TableDataInfo.build(page);
     }
+
+    /**
+     * 分页查询商品简化列表(用于选择弹窗)
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 商品简化分页列表
+     */
+    @Override
+    public TableDataInfo<ProductBaseSimpleVo> querySimplePageList(ProductBaseBo bo, PageQuery pageQuery) {
+        Page<ProductBaseSimpleVo> page = baseMapper.selectSimplePage(pageQuery.build(), bo);
+        return TableDataInfo.build(page);
+    }
 }

+ 33 - 7
ruoyi-modules/ruoyi-product/src/main/java/org/dromara/product/service/impl/ProductBlacklistServiceImpl.java

@@ -1,6 +1,8 @@
 package org.dromara.product.service.impl;
 
+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 +12,8 @@ import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.dromara.customer.api.RemoteCustomerService;
+import org.dromara.customer.api.domain.CustomerApiVo;
 import org.springframework.stereotype.Service;
 import org.dromara.product.domain.bo.ProductBlacklistBo;
 import org.dromara.product.domain.vo.ProductBlacklistVo;
@@ -17,9 +21,8 @@ import org.dromara.product.domain.ProductBlacklist;
 import org.dromara.product.mapper.ProductBlacklistMapper;
 import org.dromara.product.service.IProductBlacklistService;
 
-import java.util.List;
-import java.util.Map;
-import java.util.Collection;
+import java.util.*;
+import java.util.stream.Collectors;
 
 /**
  * 产品黑名单Service业务层处理
@@ -30,10 +33,13 @@ import java.util.Collection;
 @Slf4j
 @RequiredArgsConstructor
 @Service
-public class ProductBlacklistServiceImpl  extends ServiceImpl<ProductBlacklistMapper, ProductBlacklist> implements IProductBlacklistService {
+public class ProductBlacklistServiceImpl extends ServiceImpl<ProductBlacklistMapper, ProductBlacklist> implements IProductBlacklistService {
 
     private final ProductBlacklistMapper baseMapper;
 
+    @DubboReference
+    private RemoteCustomerService remoteCustomerService;
+
     /**
      * 查询产品黑名单
      *
@@ -54,9 +60,29 @@ public class ProductBlacklistServiceImpl  extends ServiceImpl<ProductBlacklistMa
      */
     @Override
     public TableDataInfo<ProductBlacklistVo> queryPageList(ProductBlacklistBo bo, PageQuery pageQuery) {
-        LambdaQueryWrapper<ProductBlacklist> lqw = buildQueryWrapper(bo);
-        Page<ProductBlacklistVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
-        return TableDataInfo.build(result);
+        Page<ProductBlacklistVo> page = baseMapper.selectBlacklistPage(pageQuery.build(), bo);
+
+        // 补充客户编号和名称(远程调用)
+        List<ProductBlacklistVo> records = page.getRecords();
+        if (CollUtil.isNotEmpty(records)) {
+            Set<Long> customerIds = records.stream()
+                .map(ProductBlacklistVo::getCustomerId)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+
+            if (!customerIds.isEmpty()) {
+                Map<Long, CustomerApiVo> customerMap = remoteCustomerService.selectCustomerByIds(customerIds);
+                records.forEach(vo -> {
+                    CustomerApiVo customer = customerMap.get(vo.getCustomerId());
+                    if (customer != null) {
+                        vo.setCustomerNo(customer.getCustomerNo());
+                        vo.setCustomerName(customer.getCustomerName());
+                    }
+                });
+            }
+        }
+
+        return TableDataInfo.build(page);
     }
 
     /**

+ 52 - 0
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBaseMapper.xml

@@ -193,4 +193,56 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
         ORDER BY b.create_time DESC
     </select>
 
+    <!-- 商品简化列表查询(用于选择弹窗) -->
+    <select id="selectSimplePage" resultType="org.dromara.product.domain.vo.ProductBaseSimpleVo">
+        SELECT
+            b.id,
+            b.product_no AS productNo,
+            b.item_name AS itemName,
+            b.product_image AS productImage,
+            p.market_price AS marketPrice,
+            p.member_price AS memberPrice,
+            e.specifications_code AS specification,
+            b.top_category_id AS topCategoryId,
+            tc.category_name AS topCategoryName,
+            b.medium_category_id AS mediumCategoryId,
+            mc.category_name AS mediumCategoryName,
+            b.bottom_category_id AS bottomCategoryId,
+            bc.category_name AS bottomCategoryName,
+            b.home_recommended AS homeRecommended,
+            b.category_recommendation AS categoryRecommendation,
+            b.cart_recommendation AS cartRecommendation,
+            b.recommended_product_order AS recommendedProductOrder,
+            b.is_popular AS isPopular,
+            b.product_status AS productStatus
+        FROM product_base b
+        LEFT JOIN product_price_inventory p ON b.id = p.product_id AND p.del_flag = '0'
+        LEFT JOIN product_extend e ON b.id = e.product_id AND e.del_flag = '0'
+        LEFT JOIN product_category tc ON b.top_category_id = tc.id AND tc.del_flag = '0'
+        LEFT JOIN product_category mc ON b.medium_category_id = mc.id AND mc.del_flag = '0'
+        LEFT JOIN product_category bc ON b.bottom_category_id = bc.id AND bc.del_flag = '0'
+        <where>
+            b.del_flag = '0'
+            <if test="bo.productNo != null and bo.productNo != ''">
+                AND b.product_no LIKE CONCAT('%', #{bo.productNo}, '%')
+            </if>
+            <if test="bo.itemName != null and bo.itemName != ''">
+                AND b.item_name LIKE CONCAT('%', #{bo.itemName}, '%')
+            </if>
+            <if test="bo.productStatus != null and bo.productStatus != ''">
+                AND b.product_status = #{bo.productStatus}
+            </if>
+            <if test="bo.topCategoryId != null">
+                AND b.top_category_id = #{bo.topCategoryId}
+            </if>
+            <if test="bo.mediumCategoryId != null">
+                AND b.medium_category_id = #{bo.mediumCategoryId}
+            </if>
+            <if test="bo.bottomCategoryId != null">
+                AND b.bottom_category_id = #{bo.bottomCategoryId}
+            </if>
+        </where>
+        ORDER BY b.create_time DESC
+    </select>
+
 </mapper>

+ 41 - 0
ruoyi-modules/ruoyi-product/src/main/resources/mapper/product/ProductBlacklistMapper.xml

@@ -4,4 +4,45 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 <mapper namespace="org.dromara.product.mapper.ProductBlacklistMapper">
 
+    <!-- 分页查询黑名单列表(关联商品和分类) -->
+    <select id="selectBlacklistPage" resultType="org.dromara.product.domain.vo.ProductBlacklistVo">
+        SELECT
+            pb.id,
+            pb.customer_id AS customerId,
+            pb.product_id AS productId,
+            p.product_no AS productNo,
+            p.item_name AS productName,
+            pb.product_category_id AS productCategoryId,
+            pc.category_no AS categoryNo,
+            pc.category_name AS categoryName,
+            pb.remark
+        FROM product_blacklist pb
+        LEFT JOIN product_base p ON pb.product_id = p.id AND p.del_flag = '0'
+        LEFT JOIN product_category pc ON pb.product_category_id = pc.id AND pc.del_flag = '0'
+        <where>
+            pb.del_flag = '0'
+            <if test="bo.customerId != null">
+                AND pb.customer_id = #{bo.customerId}
+            </if>
+            <if test="bo.productId != null">
+                AND pb.product_id = #{bo.productId}
+            </if>
+            <if test="bo.productCategoryId != null">
+                AND pb.product_category_id = #{bo.productCategoryId}
+            </if>
+            <if test="bo.platformCode != null and bo.platformCode != ''">
+                AND pb.platform_code = #{bo.platformCode}
+            </if>
+            <!-- 商品黑名单:productId 不为空 -->
+            <if test="bo.blacklistType != null and bo.blacklistType == 'product'">
+                AND pb.product_id IS NOT NULL
+            </if>
+            <!-- 分类黑名单:productId 为空 -->
+            <if test="bo.blacklistType != null and bo.blacklistType == 'category'">
+                AND pb.product_id IS NULL
+            </if>
+        </where>
+        ORDER BY pb.id DESC
+    </select>
+
 </mapper>

+ 4 - 4
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysDept.java

@@ -92,10 +92,10 @@ public class SysDept extends TenantEntity {
 
     private String isCompanyFlag;
 
-    /**
-     * 客户ID
-     */
-    private Long customerId;
+//    /**
+//     * 客户ID
+//     */
+//    private Long customerId;
 
 
     /**

+ 7 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/dubbo/RemoteDeptServiceImpl.java

@@ -77,6 +77,13 @@ public class RemoteDeptServiceImpl implements RemoteDeptService {
         return BeanUtil.copyProperties(dept, RemoteDeptVo.class);
     }
 
+    @Override
+    public RemoteDeptVo updateDept(RemoteDeptVo vo) {
+        SysDeptBo dept = BeanUtil.copyProperties(vo, SysDeptBo.class);
+        sysDeptService.updateDept(dept);
+        return BeanUtil.copyProperties(dept, RemoteDeptVo.class);
+    }
+
     @Override
     public List<RemoteDeptVo> selectDeptByIds(List<Long> deptIds) {
         List<SysDeptVo> sysDeptVos = sysDeptService.selectDeptByIds(deptIds);

+ 67 - 0
script/sql/global_setting_menu.sql

@@ -0,0 +1,67 @@
+-- =============================================
+-- 全局设置菜单
+-- =============================================
+
+-- 一级菜单:全局设置
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000100, '全局设置', 0, 12, 'globalSetting', '', 1, 0, 'M', '0', '0', '', 'setting', 1, NOW(), NULL, NULL, '全局设置目录', 'opm');
+
+-- 二级菜单:客户行业
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000101, '客户行业', 1877000000000000100, 1, 'industry', 'platform/globalSetting/industry/index', 1, 0, 'C', '0', '0', 'customer:industryCategory:list', '#', 1, NOW(), NULL, NULL, '客户行业菜单', 'opm');
+
+-- 二级菜单:价格区间
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000102, '价格区间', 1877000000000000100, 2, 'priceRange', 'platform/globalSetting/priceRange/index', 1, 0, 'C', '0', '0', 'globalSetting:priceRange:list', '#', 1, NOW(), NULL, NULL, '价格区间菜单', 'opm');
+
+-- 二级菜单:适配场景
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000103, '适配场景', 1877000000000000100, 3, 'scene', 'platform/globalSetting/scene/index', 1, 0, 'C', '0', '0', 'globalSetting:scene:list', '#', 1, NOW(), NULL, NULL, '适配场景菜单', 'opm');
+
+-- 二级菜单:项目类型
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000104, '项目类型', 1877000000000000100, 4, 'projectType', 'platform/globalSetting/projectType/index', 1, 0, 'C', '0', '0', 'globalSetting:projectType:list', '#', 1, NOW(), NULL, NULL, '项目类型菜单', 'opm');
+
+-- 二级菜单:采购分类
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000105, '采购分类', 1877000000000000100, 5, 'purchaseCategory', 'platform/globalSetting/purchaseCategory/index', 1, 0, 'C', '0', '0', 'globalSetting:purchaseCategory:list', '#', 1, NOW(), NULL, NULL, '采购分类菜单', 'opm');
+
+-- 二级菜单:推荐标签
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000106, '推荐标签', 1877000000000000100, 6, 'recommendTag', 'platform/globalSetting/recommendTag/index', 1, 0, 'C', '0', '0', 'globalSetting:recommendTag:list', '#', 1, NOW(), NULL, NULL, '推荐标签菜单', 'opm');
+
+-- 二级菜单:售后服务
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000107, '售后服务', 1877000000000000100, 7, 'afterSale', 'platform/globalSetting/afterSale/index', 1, 0, 'C', '0', '0', 'globalSetting:afterSale:list', '#', 1, NOW(), NULL, NULL, '售后服务菜单', 'opm');
+
+-- 二级菜单:重量单位
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000108, '重量单位', 1877000000000000100, 8, 'weightUnit', 'platform/globalSetting/weightUnit/index', 1, 0, 'C', '0', '0', 'globalSetting:weightUnit:list', '#', 1, NOW(), NULL, NULL, '重量单位菜单', 'opm');
+
+-- 二级菜单:体积单位
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000109, '体积单位', 1877000000000000100, 9, 'volumeUnit', 'platform/globalSetting/volumeUnit/index', 1, 0, 'C', '0', '0', 'globalSetting:volumeUnit:list', '#', 1, NOW(), NULL, NULL, '体积单位菜单', 'opm');
+
+-- 二级菜单:服务保证
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000110, '服务保证', 1877000000000000100, 10, 'serviceGuarantee', 'platform/globalSetting/serviceGuarantee/index', 1, 0, 'C', '0', '0', 'globalSetting:serviceGuarantee:list', '#', 1, NOW(), NULL, NULL, '服务保证菜单', 'opm');
+
+-- 二级菜单:服务时间
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000111, '服务时间', 1877000000000000100, 11, 'serviceTime', 'platform/globalSetting/serviceTime/index', 1, 0, 'C', '0', '0', 'globalSetting:serviceTime:list', '#', 1, NOW(), NULL, NULL, '服务时间菜单', 'opm');
+
+-- 二级菜单:维保类型
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000112, '维保类型', 1877000000000000100, 12, 'maintenanceType', 'platform/globalSetting/maintenanceType/index', 1, 0, 'C', '0', '0', 'globalSetting:maintenanceType:list', '#', 1, NOW(), NULL, NULL, '维保类型菜单', 'opm');
+
+-- 二级菜单:维保项目
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000113, '维保项目', 1877000000000000100, 13, 'maintenanceProject', 'platform/globalSetting/maintenanceProject/index', 1, 0, 'C', '0', '0', 'globalSetting:maintenanceProject:list', '#', 1, NOW(), NULL, NULL, '维保项目菜单', 'opm');
+
+-- 二级菜单:维保时间
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000114, '维保时间', 1877000000000000100, 14, 'maintenanceTime', 'platform/globalSetting/maintenanceTime/index', 1, 0, 'C', '0', '0', 'globalSetting:maintenanceTime:list', '#', 1, NOW(), NULL, NULL, '维保时间菜单', 'opm');
+
+-- 二级菜单:模板管理
+INSERT INTO sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_by, create_time, update_by, update_time, remark, platform_code)
+VALUES (1877000000000000115, '模板管理', 1877000000000000100, 15, 'template', 'platform/globalSetting/template/index', 1, 0, 'C', '0', '0', 'globalSetting:template:list', '#', 1, NOW(), NULL, NULL, '模板管理菜单', 'opm');