Browse Source

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

肖路 18 hours ago
parent
commit
340fee291e
100 changed files with 7246 additions and 49 deletions
  1. 3 1
      ruoyi-common/ruoyi-common-mybatis/src/main/java/org/dromara/common/mybatis/interceptor/PlatformDataScopeInterceptor.java
  2. 51 25
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerPoolController.java
  3. 6 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerListBo.java
  4. 3 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SalesleadsBo.java
  5. 3 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/SalesleadsVo.java
  6. 4 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/TeamMemberVo.java
  7. 1 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/ICustomerPoolService.java
  8. 5 1
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/CustomerPoolServiceImpl.java
  9. 4 6
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SalesleadsServiceImpl.java
  10. 33 0
      ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/TeamMemberServiceImpl.java
  11. 9 9
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerPoolMapper.xml
  12. 31 2
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SalesleadsMapper.xml
  13. 4 2
      ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/TeamMemberMapper.xml
  14. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhAdConfigController.java
  15. 116 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhCarouselConfigController.java
  16. 115 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhCategoryMainController.java
  17. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhCategorySubController.java
  18. 116 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhHeaderMenuController.java
  19. 114 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhMallConfigController.java
  20. 116 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhRecommendCategoryConfigController.java
  21. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhRecommendThemeConfigController.java
  22. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhScenarioConfigController.java
  23. 112 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/pc/PcDkhDesignController.java
  24. 82 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhAdConfig.java
  25. 72 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhCarouselConfig.java
  26. 72 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhCategoryMain.java
  27. 82 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhCategorySub.java
  28. 67 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhHeaderMenu.java
  29. 89 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhMallConfig.java
  30. 87 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhRecommendCategoryConfig.java
  31. 57 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhRecommendThemeConfig.java
  32. 89 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhScenarioConfig.java
  33. 74 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhAdConfigBo.java
  34. 64 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhCarouselConfigBo.java
  35. 64 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhCategoryMainBo.java
  36. 74 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhCategorySubBo.java
  37. 59 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhHeaderMenuBo.java
  38. 80 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhMallConfigBo.java
  39. 79 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhRecommendCategoryConfigBo.java
  40. 49 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhRecommendThemeConfigBo.java
  41. 81 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhScenarioConfigBo.java
  42. 92 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhAdConfigVo.java
  43. 80 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhCarouselConfigVo.java
  44. 96 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhCategoryMainVo.java
  45. 95 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhCategorySubVo.java
  46. 77 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhHeaderMenuVo.java
  47. 99 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhMallConfigVo.java
  48. 94 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhRecommendCategoryConfigVo.java
  49. 62 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhRecommendThemeConfigVo.java
  50. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhScenarioConfigVo.java
  51. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhAdConfigMapper.java
  52. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhCarouselConfigMapper.java
  53. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhCategoryMainMapper.java
  54. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhCategorySubMapper.java
  55. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhHeaderMenuMapper.java
  56. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhMallConfigMapper.java
  57. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhRecommendCategoryConfigMapper.java
  58. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhRecommendThemeConfigMapper.java
  59. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhScenarioConfigMapper.java
  60. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhAdConfigService.java
  61. 78 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhCarouselConfigService.java
  62. 78 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhCategoryMainService.java
  63. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhCategorySubService.java
  64. 78 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhHeaderMenuService.java
  65. 78 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhMallConfigService.java
  66. 78 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhRecommendCategoryConfigService.java
  67. 72 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhRecommendThemeConfigService.java
  68. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhScenarioConfigService.java
  69. 141 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhAdConfigServiceImpl.java
  70. 153 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhCarouselConfigServiceImpl.java
  71. 612 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhCategoryMainServiceImpl.java
  72. 140 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhCategorySubServiceImpl.java
  73. 167 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhHeaderMenuServiceImpl.java
  74. 156 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhMallConfigServiceImpl.java
  75. 175 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhRecommendCategoryConfigServiceImpl.java
  76. 160 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhRecommendThemeConfigServiceImpl.java
  77. 142 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhScenarioConfigServiceImpl.java
  78. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhAdConfigMapper.xml
  79. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhCarouselConfigMapper.xml
  80. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhCategoryMainMapper.xml
  81. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhCategorySubMapper.xml
  82. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhHeaderMenuMapper.xml
  83. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhMallConfigMapper.xml
  84. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhRecommendCategoryConfigMapper.xml
  85. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhRecommendThemeConfigMapper.xml
  86. 7 0
      ruoyi-modules/ruoyi-mall/src/main/resources/mapper/mall/DkhScenarioConfigMapper.xml
  87. 73 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcDkhMenuSettings.java
  88. 116 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhBottomMenuController.java
  89. 114 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhCopyrightInfoController.java
  90. 115 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhMobileHuicaiConfigController.java
  91. 115 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhTopMenuController.java
  92. 72 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhBottomMenu.java
  93. 97 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhCopyrightInfo.java
  94. 77 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhMobileHuicaiConfig.java
  95. 72 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhTopMenu.java
  96. 1 1
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/SysAnnouncement.java
  97. 64 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/DkhBottomMenuBo.java
  98. 89 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/DkhCopyrightInfoBo.java
  99. 69 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/DkhMobileHuicaiConfigBo.java
  100. 64 0
      ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/DkhTopMenuBo.java

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

@@ -128,7 +128,8 @@ public class PlatformDataScopeInterceptor implements Interceptor {
         "maintenance_server_item",
         "contract_supply",
         "team_member",
-        "ep_"
+        "ep_",
+        "dkh_"
         // 注意:前缀匹配需特殊处理(如 qrtz_),见 isIgnoreTable 方法
     ));
 
@@ -252,6 +253,7 @@ public class PlatformDataScopeInterceptor implements Interceptor {
             || tableName.startsWith("protocol_")
             || tableName.startsWith("ns_diy_")
             || tableName.startsWith("ep_")
+            || tableName.startsWith("dkh_")
             ;
     }
 

+ 51 - 25
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/controller/CustomerPoolController.java

@@ -34,7 +34,7 @@ import java.util.List;
 /**
  * 客户公海与有效客户统一控制器
  *
- * @author Antigravity
+ * @author tys
  */
 @Validated
 @RequiredArgsConstructor
@@ -64,41 +64,67 @@ public class CustomerPoolController extends BaseController {
      */
     @GetMapping("/list")
     public TableDataInfo<CustomerListVo> list(CustomerListBo bo, PageQuery pageQuery) {
+        return allList(bo, pageQuery);
+    }
+
+    /**
+     * 我负责的客户列表
+     */
+    @GetMapping("/mineList")
+    public TableDataInfo<CustomerListVo> mineList(CustomerListBo bo, PageQuery pageQuery) {
         Long userId = LoginHelper.getLoginUser().getUserId();
         RemoteComStaffVo remoteComStaffVo = remoteComStaffService.selectStaffByUserId(userId);
         Long staffId = (remoteComStaffVo != null) ? remoteComStaffVo.getStaffId() : null;
 
-        boolean isAdmin = LoginHelper.isSuperAdmin() || LoginHelper.isTenantAdmin();
-        bo.getParams().put("isAdmin", isAdmin ? "true" : "false");
-        bo.getParams().put("createBy", userId);
+        bo.setSalesPersonId(staffId != null ? staffId : -1L);
+        bo.setServiceStaffId(null);
+        bo.setCreateBy(null);
+        bo.setActiveTab("mine");
+        bo.setIsHighSeas("false");
+        return customerPoolService.queryCustomerListPage(bo, pageQuery);
+    }
 
-        if ("mine".equals(bo.getActiveTab())) {
+    /**
+     * 我参与的客户列表
+     */
+    @GetMapping("/involvedList")
+    public TableDataInfo<CustomerListVo> involvedList(CustomerListBo bo, PageQuery pageQuery) {
+        Long userId = LoginHelper.getLoginUser().getUserId();
+        RemoteComStaffVo remoteComStaffVo = remoteComStaffService.selectStaffByUserId(userId);
+        Long staffId = (remoteComStaffVo != null) ? remoteComStaffVo.getStaffId() : null;
+
+        bo.setServiceStaffId(staffId != null ? staffId : -1L);
+        bo.setSalesPersonId(null);
+        bo.setCreateBy(null);
+        bo.setActiveTab("involved");
+        bo.setIsHighSeas("false");
+        return customerPoolService.queryCustomerListPage(bo, pageQuery);
+    }
+
+    @GetMapping("/allList")
+    public TableDataInfo<CustomerListVo> allList(CustomerListBo bo, PageQuery pageQuery) {
+        // 仅系统超级管理员(userId=1)可看全部客户;
+        // 租户管理员(roleKey=admin)属于普通 CRM 用户,仍需按"我负责+我参与"过滤
+        boolean isAdmin = LoginHelper.isSuperAdmin();
+        if (isAdmin) {
+            bo.setIsAdmin("true");
+        } else {
+            bo.setIsAdmin("false");
+            Long userId = LoginHelper.getLoginUser().getUserId();
+            RemoteComStaffVo remoteComStaffVo = remoteComStaffService.selectStaffByUserId(userId);
+            Long staffId = (remoteComStaffVo != null) ? remoteComStaffVo.getStaffId() : null;
+            // salesPersonId 用 staffId 匹配 ci.sales_person_id(我负责的)和 team_member.user_no(我参与的)
             bo.setSalesPersonId(staffId != null ? staffId : -1L);
             bo.setServiceStaffId(null);
-            bo.setCreateBy(null);
-        } else if ("involved".equals(bo.getActiveTab())) {
-            bo.setServiceStaffId(staffId != null ? staffId : -1L);
-            bo.setSalesPersonId(null);
-            bo.setCreateBy(null);
-        } else {
-            // "all" tab
-            if (isAdmin) {
-                // 管理员在"全部客户"时查看所有数据,不加自己ID的限制
-                bo.setSalesPersonId(null);
-                bo.setServiceStaffId(null);
-                bo.setCreateBy(null);
-            } else {
-                // 普通用户在"全部客户"时仍需要限制查看自己创建的/负责的/参与的
-                bo.setCreateBy(userId);
-                bo.setSalesPersonId(staffId != null ? staffId : -1L);
-                bo.setServiceStaffId(staffId != null ? staffId : -1L);
-            }
         }
-        bo.setIsHighSeas("false"); // 强制为有效客户
-
+        bo.setActiveTab("all");
+        bo.setIsHighSeas("false");
+        bo.setCreateBy(null);
+        bo.getParams().remove("createBy");
         return customerPoolService.queryCustomerListPage(bo, pageQuery);
     }
 
+
     /**
      * 获取客户详细信息
      */

+ 6 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/CustomerListBo.java

@@ -52,4 +52,10 @@ public class CustomerListBo extends BaseEntity {
 
     /** 当前选中的 Tab: mine / involved / all */
     private String activeTab;
+
+    /** 是否为管理员 (true: 是, false: 否) */
+    private String isAdmin;
+
+    /** 当前登录用户的系统 userId(用于 team_member.user_no 匹配,区别于 staffId) */
+    private Long currentUserId;
 }

+ 3 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/bo/SalesleadsBo.java

@@ -138,4 +138,7 @@ public class SalesleadsBo extends TenantEntity {
 
     @Schema(description = "成交结果")
     private Integer dealResult;
+
+    @Schema(description = "Tab类型: managed(我负责的) / participated(我参与的) / all(全部)")
+    private String tabType;
 }

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

@@ -111,6 +111,9 @@ public class SalesleadsVo implements Serializable {
     @Schema(description = "状态")
     private String status;
 
+    @Schema(description = "项目状态名称")
+    private String statusName;
+
     @Schema(description = "平台标识")
     private String platformCode;
 

+ 4 - 1
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/domain/vo/TeamMemberVo.java

@@ -30,9 +30,12 @@ public class TeamMemberVo implements Serializable {
     @Schema(description = "对象编号")
     private String objectNo;
 
-    @Schema(description = "用户编号")
+    @Schema(description = "用户编号(实际上是staffId)")
     private Long userNo;
 
+    @Schema(description = "系统用户ID(由关联com_staff得出)")
+    private Long userId;
+
     @Schema(description = "真实姓名")
     private String realName;
 

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

@@ -13,7 +13,7 @@ import java.util.List;
 /**
  * 客户公海与有效客户Service接口
  *
- * @author Antigravity
+ * @author tys
  */
 public interface ICustomerPoolService {
 

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

@@ -25,6 +25,7 @@ import org.dromara.customer.mapper.CrmStaffMapper;
 import org.dromara.customer.service.ICustomerPoolService;
 import org.dromara.customer.service.ICustomerInfoService;
 import org.dromara.system.api.*;
+import org.dromara.system.api.domain.vo.RemoteComStaffVo;
 import org.dromara.system.api.domain.vo.RemoteDictDataVo;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import org.springframework.stereotype.Service;
@@ -36,7 +37,7 @@ import java.util.stream.Collectors;
 /**
  * 客户公海与有效客户Service业务层处理
  *
- * @author Antigravity
+ * @author tys
  */
 @Slf4j
 @RequiredArgsConstructor
@@ -69,6 +70,9 @@ public class CustomerPoolServiceImpl implements ICustomerPoolService {
             bo.setIsHighSeas(isHighSeasObj != null ? String.valueOf(isHighSeasObj) : "false");
         }
 
+        log.info("queryCustomerListPage trace - isHighSeas: {}, activeTab: {}, salesPersonId: {}, serviceStaffId: {}, isAdmin: {}", 
+                 bo.getIsHighSeas(), bo.getActiveTab(), bo.getSalesPersonId(), bo.getServiceStaffId(), bo.getIsAdmin());
+
         Page<CustomerListVo> page = customerPoolMapper.selectCustomerListPage(pageQuery.build(), bo);
         List<CustomerListVo> records = page.getRecords();
 

+ 4 - 6
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/SalesleadsServiceImpl.java

@@ -409,7 +409,7 @@ public class SalesleadsServiceImpl implements ISalesleadsService {
     }
 
     /**
-     * 应用用户权限:只允许查看自己是负责人或者产品支持的项目
+     * 应用用户权限:根据 tabType(我负责的、我参与的、全部)做相应的数据权限过滤
      */
     private void applyUserPermission(SalesleadsBo bo) {
         if (bo == null) {
@@ -417,15 +417,13 @@ public class SalesleadsServiceImpl implements ISalesleadsService {
         }
         if (!LoginHelper.isSuperAdmin()) {
             RemoteComStaffVo staffVo = remoteComStaffService.selectStaffByUserId(LoginHelper.getUserId());
+            Long staffId = (staffVo != null && staffVo.getStaffId() != null) ? staffVo.getStaffId() : -1L;
             if (bo.getParams() == null) {
                 bo.setParams(new java.util.HashMap<>());
             }
+            bo.getParams().put("currentUserId", staffId);
             bo.getParams().put("restrictToUser", true);
-            if (staffVo != null && staffVo.getStaffId() != null) {
-                bo.getParams().put("currentUserId", staffVo.getStaffId());
-            } else {
-                bo.getParams().put("currentUserId", -1L);
-            }
+            bo.getParams().put("tabType", bo.getTabType());
         }
     }
 

+ 33 - 0
ruoyi-modules/ruoyi-customer/src/main/java/org/dromara/customer/service/impl/TeamMemberServiceImpl.java

@@ -15,13 +15,20 @@ import org.dromara.customer.mapper.TeamMemberMapper;
 import org.dromara.customer.service.IOperationLogService;
 import org.dromara.customer.service.ITeamMemberService;
 import org.dromara.system.api.RemoteDictService;
+import org.dromara.system.api.RemoteComStaffService;
 import org.dromara.system.api.domain.vo.RemoteDictDataVo;
+import org.dromara.system.api.domain.vo.RemoteComStaffVo;
 import org.apache.dubbo.config.annotation.DubboReference;
 import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
 import java.util.Collection;
 import java.util.List;
+import java.util.Collections;
+import java.util.Map;
+import java.util.Set;
+import java.util.Objects;
+import java.util.stream.Collectors;
 
 /**
  * 团队成员 Service 业务层处理
@@ -40,6 +47,9 @@ public class TeamMemberServiceImpl implements ITeamMemberService {
     @DubboReference
     private RemoteDictService remoteDictService;
 
+    @DubboReference
+    private RemoteComStaffService remoteComStaffService;
+
     /**
      * 查询
      */
@@ -47,6 +57,12 @@ public class TeamMemberServiceImpl implements ITeamMemberService {
     public TeamMemberVo queryById(Long id) {
         TeamMemberVo vo = baseMapper.selectVoById(id);
         if (vo != null) {
+            if (vo.getUserNo() != null) {
+                List<RemoteComStaffVo> staffList = remoteComStaffService.selectStaffByIds(Collections.singleton(vo.getUserNo()));
+                if (staffList != null && !staffList.isEmpty()) {
+                    vo.setUserId(staffList.get(0).getUserId());
+                }
+            }
             translateMember(vo);
         }
         return vo;
@@ -59,6 +75,23 @@ public class TeamMemberServiceImpl implements ITeamMemberService {
     public List<TeamMemberVo> queryByObjectNo(String objectNo) {
         List<TeamMemberVo> list = baseMapper.selectByObjectNo(objectNo);
         if (list != null && !list.isEmpty()) {
+            Set<Long> staffIds = list.stream()
+                .map(TeamMemberVo::getUserNo)
+                .filter(Objects::nonNull)
+                .collect(Collectors.toSet());
+            if (!staffIds.isEmpty()) {
+                List<RemoteComStaffVo> staffList = remoteComStaffService.selectStaffByIds(staffIds);
+                if (staffList != null) {
+                    Map<Long, Long> staffIdToUserIdMap = staffList.stream()
+                        .filter(s -> s.getStaffId() != null && s.getUserId() != null)
+                        .collect(Collectors.toMap(RemoteComStaffVo::getStaffId, RemoteComStaffVo::getUserId, (v1, v2) -> v1));
+                    list.forEach(vo -> {
+                        if (vo.getUserNo() != null) {
+                            vo.setUserId(staffIdToUserIdMap.get(vo.getUserNo()));
+                        }
+                    });
+                }
+            }
             list.forEach(this::translateMember);
         }
         return list;

+ 9 - 9
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/CustomerPoolMapper.xml

@@ -54,19 +54,19 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                               AND tm.is_delete = 0
                         )
                     </if>
-                    <if test="(bo.activeTab == null or bo.activeTab == 'all' or bo.activeTab == '') and bo.params.isAdmin == 'false'">
+                    <!-- 全部客户:我负责的 OR 我参与的(team_member 中有记录) -->
+                    <if test="bo.activeTab == 'all' and bo.salesPersonId != null and bo.isAdmin != 'true'">
                         AND (
-                            ci.create_by = #{bo.params.createBy}
-                            OR ci.sales_person_id = #{bo.salesPersonId}
-                            OR ci.service_staff_id = #{bo.serviceStaffId}
+                            ci.sales_person_id = #{bo.salesPersonId}
                             OR ci.customer_no IN (
-                                SELECT tm.object_no FROM team_member tm 
-                                WHERE tm.user_no = #{bo.serviceStaffId} 
-                                  AND tm.data_type = 12 
+                                SELECT tm.object_no FROM team_member tm
+                                WHERE tm.user_no = #{bo.salesPersonId}
+                                  AND tm.data_type = 12
                                   AND tm.is_delete = 0
                             )
                         )
                     </if>
+
                 </otherwise>
             </choose>
             <if test="bo.platformCode != null and bo.platformCode != ''">
@@ -84,10 +84,10 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
             <if test="bo.customerLevelId != null">
                 AND ci.customer_level_id = #{bo.customerLevelId}
             </if>
-            <if test="bo.salesPersonId != null and bo.activeTab != 'mine' and (bo.activeTab != 'all' or bo.params.isAdmin == 'true')">
+            <if test="bo.salesPersonId != null and bo.activeTab != 'mine' and (bo.activeTab != 'all' or bo.isAdmin == 'true')">
                 AND ci.sales_person_id = #{bo.salesPersonId}
             </if>
-            <if test="bo.serviceStaffId != null and bo.activeTab != 'involved' and (bo.activeTab != 'all' or bo.params.isAdmin == 'true')">
+            <if test="bo.serviceStaffId != null and bo.activeTab != 'involved' and (bo.activeTab != 'all' or bo.isAdmin == 'true')">
                 AND ci.service_staff_id = #{bo.serviceStaffId}
             </if>
             <if test="bo.belongingDepartmentId != null">

+ 31 - 2
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/SalesleadsMapper.xml

@@ -6,7 +6,8 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <select id="selectSalesleadsList" resultType="org.dromara.customer.domain.vo.SalesleadsVo">
         SELECT s.*, cc.company_name AS companyName, ic.industry_category_name AS industry, d.dept_name AS deptName,
-               CASE sra.dealResult WHEN 1 THEN '赢单' WHEN 2 THEN '丢单' ELSE sra.dealResult END AS dealResult
+               CASE sra.dealResult WHEN 1 THEN '赢单' WHEN 2 THEN '丢单' ELSE sra.dealResult END AS dealResult,
+               CASE s.status WHEN '0' THEN '跟进中' WHEN '1' THEN '结案' ELSE s.status END AS statusName
         FROM salesleads s
         LEFT JOIN sys_company cc ON s.company_no COLLATE utf8mb4_unicode_ci = cc.company_code COLLATE utf8mb4_unicode_ci AND cc.del_flag = '0'
         LEFT JOIN industry_category ic ON s.profession = ic.id AND ic.del_flag = '0'
@@ -49,7 +50,35 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
                 AND sra.dealResult = #{bo.dealResult}
             </if>
             <if test="bo.params.restrictToUser == true">
-                AND (s.leader = #{bo.params.currentUserId} OR FIND_IN_SET(#{bo.params.currentUserId}, s.product_support) > 0)
+                <choose>
+                    <when test="bo.params.tabType == 'managed'">
+                        AND s.leader = #{bo.params.currentUserId}
+                    </when>
+                    <when test="bo.params.tabType == 'participated'">
+                        AND s.leader != #{bo.params.currentUserId}
+                        AND (
+                            FIND_IN_SET(#{bo.params.currentUserId}, s.product_support)
+                            OR s.id IN (
+                                SELECT CAST(tm.object_no AS UNSIGNED) FROM team_member tm
+                                WHERE tm.user_no = #{bo.params.currentUserId}
+                                  AND tm.data_type = 1
+                                  AND tm.is_delete = 0
+                            )
+                        )
+                    </when>
+                    <otherwise>
+                        AND (
+                            s.leader = #{bo.params.currentUserId}
+                            OR FIND_IN_SET(#{bo.params.currentUserId}, s.product_support)
+                            OR s.id IN (
+                                SELECT CAST(tm.object_no AS UNSIGNED) FROM team_member tm
+                                WHERE tm.user_no = #{bo.params.currentUserId}
+                                  AND tm.data_type = 1
+                                  AND tm.is_delete = 0
+                            )
+                        )
+                    </otherwise>
+                </choose>
             </if>
             ${bo.params.dataScope}
         </where>

+ 4 - 2
ruoyi-modules/ruoyi-customer/src/main/resources/mapper/customer/TeamMemberMapper.xml

@@ -6,13 +6,15 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 
     <!-- 按对象编号查询成员列表 -->
     <select id="selectByObjectNo" resultType="org.dromara.customer.domain.vo.TeamMemberVo">
-        SELECT tm.* FROM team_member tm
+        SELECT tm.* 
+        FROM team_member tm
         WHERE tm.object_no = #{objectNo} AND tm.is_delete = 0
         ORDER BY tm.iz_manager DESC, tm.create_time ASC
     </select>
 
     <select id="selectPageByObjectNo" resultType="org.dromara.customer.domain.vo.TeamMemberVo">
-        SELECT tm.* FROM team_member tm
+        SELECT tm.* 
+        FROM team_member tm
         WHERE tm.object_no = #{objectNo} AND tm.is_delete = 0
         ORDER BY tm.iz_manager DESC, tm.create_time ASC
     </select>

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhAdConfigController.java

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

+ 116 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhCarouselConfigController.java

@@ -0,0 +1,116 @@
+package org.dromara.mall.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.dromara.mall.domain.bo.DkhCategoryMainBo;
+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.mall.domain.vo.DkhCarouselConfigVo;
+import org.dromara.mall.domain.bo.DkhCarouselConfigBo;
+import org.dromara.mall.service.IDkhCarouselConfigService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 企业轮播图配置
+ * 前端访问路由地址为:/mall/carouselConfig
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/carouselConfig")
+public class DkhCarouselConfigController extends BaseController {
+
+    private final IDkhCarouselConfigService dkhCarouselConfigService;
+
+    /**
+     * 查询企业轮播图配置列表
+     */
+    //@SaCheckPermission("mall:carouselConfig:list")
+    @GetMapping("/list")
+    public TableDataInfo<DkhCarouselConfigVo> list(DkhCarouselConfigBo bo, PageQuery pageQuery) {
+        return dkhCarouselConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出企业轮播图配置列表
+     */
+    //@SaCheckPermission("mall:carouselConfig:export")
+    @Log(title = "企业轮播图配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(DkhCarouselConfigBo bo, HttpServletResponse response) {
+        List<DkhCarouselConfigVo> list = dkhCarouselConfigService.queryList(bo);
+        ExcelUtil.exportExcel(list, "企业轮播图配置", DkhCarouselConfigVo.class, response);
+    }
+
+    /**
+     * 获取企业轮播图配置详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("mall:carouselConfig:query")
+    @GetMapping("/{id}")
+    public R<DkhCarouselConfigVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(dkhCarouselConfigService.queryById(id));
+    }
+
+    /**
+     * 新增企业轮播图配置
+     */
+    //@SaCheckPermission("mall:carouselConfig:add")
+    @Log(title = "企业轮播图配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody DkhCarouselConfigBo bo) {
+        return toAjax(dkhCarouselConfigService.insertByBo(bo));
+    }
+
+    /**
+     * 修改企业轮播图配置
+     */
+    //@SaCheckPermission("mall:carouselConfig:edit")
+    @Log(title = "企业轮播图配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody DkhCarouselConfigBo bo) {
+        return toAjax(dkhCarouselConfigService.updateByBo(bo));
+    }
+
+    /**
+     * 删除企业轮播图配置
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("mall:carouselConfig:remove")
+    @Log(title = "企业轮播图配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(dkhCarouselConfigService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+    @Log(title = "企业轮播图配置", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody DkhCarouselConfigBo bo) {
+        return toAjax(dkhCarouselConfigService.updateStatus(bo));
+    }
+}

+ 115 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhCategoryMainController.java

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

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhCategorySubController.java

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

+ 116 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhHeaderMenuController.java

@@ -0,0 +1,116 @@
+package org.dromara.mall.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.dromara.mall.domain.bo.DkhCarouselConfigBo;
+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.mall.domain.vo.DkhHeaderMenuVo;
+import org.dromara.mall.domain.bo.DkhHeaderMenuBo;
+import org.dromara.mall.service.IDkhHeaderMenuService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 顶部导航菜单配置
+ * 前端访问路由地址为:/mall/headerMenu
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/headerMenu")
+public class DkhHeaderMenuController extends BaseController {
+
+    private final IDkhHeaderMenuService dkhHeaderMenuService;
+
+    /**
+     * 查询顶部导航菜单配置列表
+     */
+    //@SaCheckPermission("mall:headerMenu:list")
+    @GetMapping("/list")
+    public TableDataInfo<DkhHeaderMenuVo> list(DkhHeaderMenuBo bo, PageQuery pageQuery) {
+        return dkhHeaderMenuService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出顶部导航菜单配置列表
+     */
+    //@SaCheckPermission("mall:headerMenu:export")
+    @Log(title = "顶部导航菜单配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(DkhHeaderMenuBo bo, HttpServletResponse response) {
+        List<DkhHeaderMenuVo> list = dkhHeaderMenuService.queryList(bo);
+        ExcelUtil.exportExcel(list, "顶部导航菜单配置", DkhHeaderMenuVo.class, response);
+    }
+
+    /**
+     * 获取顶部导航菜单配置详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("mall:headerMenu:query")
+    @GetMapping("/{id}")
+    public R<DkhHeaderMenuVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(dkhHeaderMenuService.queryById(id));
+    }
+
+    /**
+     * 新增顶部导航菜单配置
+     */
+    //@SaCheckPermission("mall:headerMenu:add")
+    @Log(title = "顶部导航菜单配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody DkhHeaderMenuBo bo) {
+        return toAjax(dkhHeaderMenuService.insertByBo(bo));
+    }
+
+    /**
+     * 修改顶部导航菜单配置
+     */
+    //@SaCheckPermission("mall:headerMenu:edit")
+    @Log(title = "顶部导航菜单配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody DkhHeaderMenuBo bo) {
+        return toAjax(dkhHeaderMenuService.updateByBo(bo));
+    }
+
+    /**
+     * 删除顶部导航菜单配置
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("mall:headerMenu:remove")
+    @Log(title = "顶部导航菜单配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(dkhHeaderMenuService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+    @Log(title = "顶部导航菜单配置", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody DkhHeaderMenuBo bo) {
+        return toAjax(dkhHeaderMenuService.updateStatus(bo));
+    }
+}

+ 114 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhMallConfigController.java

@@ -0,0 +1,114 @@
+package org.dromara.mall.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.mall.domain.vo.DkhMallConfigVo;
+import org.dromara.mall.domain.bo.DkhMallConfigBo;
+import org.dromara.mall.service.IDkhMallConfigService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 商城首页配置
+ * 前端访问路由地址为:/mall/mallConfig
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/mallConfig")
+public class DkhMallConfigController extends BaseController {
+
+    private final IDkhMallConfigService dkhMallConfigService;
+
+    /**
+     * 查询商城首页配置列表
+     */
+    //@SaCheckPermission("mall:mallConfig:list")
+    @GetMapping("/list")
+    public TableDataInfo<DkhMallConfigVo> list(DkhMallConfigBo bo, PageQuery pageQuery) {
+        return dkhMallConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出商城首页配置列表
+     */
+    //@SaCheckPermission("mall:mallConfig:export")
+    @Log(title = "商城首页配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(DkhMallConfigBo bo, HttpServletResponse response) {
+        List<DkhMallConfigVo> list = dkhMallConfigService.queryList(bo);
+        ExcelUtil.exportExcel(list, "商城首页配置", DkhMallConfigVo.class, response);
+    }
+
+    /**
+     * 获取商城首页配置详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("mall:mallConfig:query")
+    @GetMapping("/{id}")
+    public R<DkhMallConfigVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(dkhMallConfigService.queryById(id));
+    }
+
+    /**
+     * 新增商城首页配置
+     */
+    //@SaCheckPermission("mall:mallConfig:add")
+    @Log(title = "商城首页配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody DkhMallConfigBo bo) {
+        return toAjax(dkhMallConfigService.insertByBo(bo));
+    }
+
+    /**
+     * 修改商城首页配置
+     */
+    //@SaCheckPermission("mall:mallConfig:edit")
+    @Log(title = "商城首页配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody DkhMallConfigBo bo) {
+        return toAjax(dkhMallConfigService.updateByBo(bo));
+    }
+
+    /**
+     * 删除商城首页配置
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("mall:mallConfig:remove")
+    @Log(title = "商城首页配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(dkhMallConfigService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 获取当前客户的商城首页配置
+     */
+    @GetMapping("/current/{customerId}")
+    public R<DkhMallConfigVo> getCurrent(@PathVariable("customerId") Long customerId) {
+        return R.ok(dkhMallConfigService.getCurrentMallConfig(customerId));
+    }
+}

+ 116 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhRecommendCategoryConfigController.java

@@ -0,0 +1,116 @@
+package org.dromara.mall.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.dromara.mall.domain.bo.DkhHeaderMenuBo;
+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.mall.domain.vo.DkhRecommendCategoryConfigVo;
+import org.dromara.mall.domain.bo.DkhRecommendCategoryConfigBo;
+import org.dromara.mall.service.IDkhRecommendCategoryConfigService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 推荐分类配置
+ * 前端访问路由地址为:/mall/recommendCategoryConfig
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/dkhRecommendCategoryConfig")
+public class DkhRecommendCategoryConfigController extends BaseController {
+
+    private final IDkhRecommendCategoryConfigService dkhRecommendCategoryConfigService;
+
+    /**
+     * 查询推荐分类配置列表
+     */
+    //@SaCheckPermission("mall:recommendCategoryConfig:list")
+    @GetMapping("/list")
+    public TableDataInfo<DkhRecommendCategoryConfigVo> list(DkhRecommendCategoryConfigBo bo, PageQuery pageQuery) {
+        return dkhRecommendCategoryConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出推荐分类配置列表
+     */
+    //@SaCheckPermission("mall:recommendCategoryConfig:export")
+    @Log(title = "推荐分类配置", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(DkhRecommendCategoryConfigBo bo, HttpServletResponse response) {
+        List<DkhRecommendCategoryConfigVo> list = dkhRecommendCategoryConfigService.queryList(bo);
+        ExcelUtil.exportExcel(list, "推荐分类配置", DkhRecommendCategoryConfigVo.class, response);
+    }
+
+    /**
+     * 获取推荐分类配置详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("mall:recommendCategoryConfig:query")
+    @GetMapping("/{id}")
+    public R<DkhRecommendCategoryConfigVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(dkhRecommendCategoryConfigService.queryById(id));
+    }
+
+    /**
+     * 新增推荐分类配置
+     */
+    //@SaCheckPermission("mall:recommendCategoryConfig:add")
+    @Log(title = "推荐分类配置", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody DkhRecommendCategoryConfigBo bo) {
+        return toAjax(dkhRecommendCategoryConfigService.insertByBo(bo));
+    }
+
+    /**
+     * 修改推荐分类配置
+     */
+    //@SaCheckPermission("mall:recommendCategoryConfig:edit")
+    @Log(title = "推荐分类配置", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody DkhRecommendCategoryConfigBo bo) {
+        return toAjax(dkhRecommendCategoryConfigService.updateByBo(bo));
+    }
+
+    /**
+     * 删除推荐分类配置
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("mall:recommendCategoryConfig:remove")
+    @Log(title = "推荐分类配置", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(dkhRecommendCategoryConfigService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 状态修改
+     */
+    @Log(title = "推荐分类配置", businessType = BusinessType.UPDATE)
+    @PutMapping("/changeStatus")
+    public R<Void> changeStatus(@RequestBody DkhRecommendCategoryConfigBo bo) {
+        return toAjax(dkhRecommendCategoryConfigService.updateStatus(bo));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhRecommendThemeConfigController.java

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

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/DkhScenarioConfigController.java

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

+ 112 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/pc/PcDkhDesignController.java

@@ -0,0 +1,112 @@
+package org.dromara.mall.controller.pc;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.mall.domain.DkhRecommendThemeConfig;
+import org.dromara.mall.domain.bo.*;
+import org.dromara.mall.domain.vo.*;
+import org.dromara.mall.service.*;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * pc大客户控制器
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/pcDkhDesign")
+public class PcDkhDesignController {
+
+    private final IDkhMallConfigService dkhMallConfigService;
+
+    private final IDkhCarouselConfigService dkhCarouselConfigService;
+
+    private final IDkhCategoryMainService dkhCategoryMainService;
+
+    private final IDkhHeaderMenuService dkhHeaderMenuService;
+
+    private final IDkhAdConfigService dkhAdConfigService;
+
+    private final IDkhScenarioConfigService dkhScenarioConfigService;
+
+    private final IDkhRecommendThemeConfigService dkhRecommendThemeConfigService ;
+
+
+    /**
+     * 获取当前搜索页面设置
+     */
+    @GetMapping("/currentSearchConfig")
+    public R<DkhMallConfigVo> getCurrentSearchConfig() {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        return R.ok(dkhMallConfigService.getCurrentMallConfig(customerId));
+    }
+
+    /**
+     * 轮播图设置
+     */
+    @GetMapping("/carouselList")
+    public TableDataInfo<DkhCarouselConfigVo> carouselList(DkhCarouselConfigBo bo, PageQuery pageQuery) {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        bo.setCustomerId(customerId);
+        bo.setStatus(1L);//启用
+        return dkhCarouselConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 分类设置
+     */
+    @GetMapping("/categoryMainList")
+    public TableDataInfo<DkhCategoryMainVo> categoryMainList(DkhCategoryMainBo bo, PageQuery pageQuery) {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        bo.setCustomerId(customerId);
+        bo.setStatus(1L);//启用
+        return dkhCategoryMainService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 头部菜单
+     */
+    @GetMapping("/headerCategoryList")
+    public TableDataInfo<DkhHeaderMenuVo> headerCategoryList(DkhHeaderMenuBo bo, PageQuery pageQuery) {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        bo.setCustomerId(customerId);
+        bo.setStatus(1L);//启用
+        return dkhHeaderMenuService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 广告模块
+     */
+    @GetMapping("/adConfigList")
+    public TableDataInfo<DkhAdConfigVo> adModuleConfigList(DkhAdConfigBo bo, PageQuery pageQuery) {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        bo.setCustomerId(customerId);
+        return dkhAdConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 场景方案设置
+     */
+    @GetMapping("/currentScenarioConfig")
+    public TableDataInfo<DkhScenarioConfigVo> getCurrentScenarioGlobalSetting(DkhScenarioConfigBo bo, PageQuery pageQuery) {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        bo.setCustomerId(customerId);
+        bo.setStatus(1L);//启用
+        return dkhScenarioConfigService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 推荐设置
+     */
+    @GetMapping("/recommendThemeConfig")
+    public R<DkhRecommendThemeConfigVo> getCurrentRecommendThemeConfig() {
+        Long customerId = LoginHelper.getLoginUser().getCustomerId();
+        return R.ok(dkhRecommendThemeConfigService.getCurrentRecommendThemeConfig(customerId));
+    }
+}

+ 82 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhAdConfig.java

@@ -0,0 +1,82 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 广告模块配置对象 dkh_ad_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_ad_config")
+public class DkhAdConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 模块位置索引:0-采购场景, 1-合作品牌, 2-排行榜, 3-企业精选(大图), 4-重磅新品
+     */
+    private Long moduleIndex;
+
+    /**
+     * 主标题文本
+     */
+    private String mainTitle;
+
+    /**
+     * 主标题字体颜色
+     */
+    private String mainTitleColor;
+
+    /**
+     * 副标题文本
+     */
+    private String subTitle;
+
+    /**
+     * 副标题字体颜色
+     */
+    private String subTitleColor;
+
+    /**
+     * 副标题跳转链接 (支持外链)
+     */
+    private String subTitleLink;
+
+    /**
+     * 商品或品牌列表数据
+     */
+    private String itemsJson;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 72 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhCarouselConfig.java

@@ -0,0 +1,72 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 企业轮播图配置对象 dkh_carousel_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_carousel_config")
+public class DkhCarouselConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 轮播图图片地址
+     */
+    private String imageUrl;
+
+    /**
+     * 点击跳转的目标链接地址
+     */
+    private String linkUrl;
+
+    /**
+     * 打开方式: _blank (新窗口), _self (当前窗口)
+     */
+    private String target;
+
+    /**
+     * 排序权重,数值越小越靠前
+     */
+    private Long sortOrder;
+
+    /**
+     * 状态: 1-启用, 0-禁用
+     */
+    private Long status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 72 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhCategoryMain.java

@@ -0,0 +1,72 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 分类设置主对象 dkh_category_main
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_category_main")
+public class DkhCategoryMain extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 一级菜单名称(如:办公电脑 / 办公打印)
+     */
+    private String name;
+
+    /**
+     * 标签设置列表 [{"name":"热销", "link":"..."}]
+     */
+    private String tagsJson;
+
+    /**
+     * 启用状态:1-开启,0-关闭
+     */
+    private Long status;
+
+    /**
+     * 右滑面板配置:主副标题及便签列表
+     */
+    private String panelConfigJson;
+
+    /**
+     * 远程商品分类表中同步过来的一级分类ID
+     */
+    private Long syncCategoryId;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 82 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhCategorySub.java

@@ -0,0 +1,82 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 分类设置子菜单对象 dkh_category_sub
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_category_sub")
+public class DkhCategorySub extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 所属一级分类ID(关联 dkh_category_main.id)
+     */
+    private Long mainCategoryId;
+
+    /**
+     * 父级菜单ID(0代表是一级子菜单,即树的第二层)
+     */
+    private Long parentId;
+
+    /**
+     * 分类名称
+     */
+    private String name;
+
+    /**
+     * 当前层级深度(2=二级分类, 3=三级分类)
+     */
+    private Long level;
+
+    /**
+     * 排序权重(数值越小越靠前)
+     */
+    private Long sortOrder;
+
+    /**
+     * 启用状态:1-开启,0-关闭
+     */
+    private Long status;
+
+    /**
+     * 远程商品分类表中同步过来的分类ID
+     */
+    private Long syncCategoryId;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 67 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhHeaderMenu.java

@@ -0,0 +1,67 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 顶部导航菜单配置对象 dkh_header_menu
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_header_menu")
+public class DkhHeaderMenu extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 菜单标题名称(如:公共采购)
+     */
+    private String title;
+
+    /**
+     * 跳转地址
+     */
+    private String linkUrl;
+
+    /**
+     * 排序权重(数值越小越靠前,支持拖拽排序)
+     */
+    private Long sortOrder;
+
+    /**
+     * 启用状态:1-启用,0-禁用
+     */
+    private Long status;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 89 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhMallConfig.java

@@ -0,0 +1,89 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 商城首页配置对象 dkh_mall_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_mall_config")
+public class DkhMallConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于区分不同企业的配置
+     */
+    private Long customerId;
+
+    /**
+     * 主标题(如:优易慧采)
+     */
+    private String mainTitle;
+
+    /**
+     * 企业Logo图片地址
+     */
+    private String logoUrl;
+
+    /**
+     * 搜索框提示文字
+     */
+    private String searchPlaceholder;
+
+    /**
+     * 搜索热词列表
+     */
+    private String hotWords;
+
+    /**
+     * 右侧按钮文字(如:我的采购单)
+     */
+    private String btnText;
+
+    /**
+     * 主题色 HEX值
+     */
+    private String themeColor;
+
+    /**
+     * 状态:1启用 0禁用
+     */
+    private Long status;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /*分类主题色*/
+    private String categoryThemeColor;
+
+    /*头部主题色*/
+    private String headerThemeColor;
+
+
+
+}

+ 87 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhRecommendCategoryConfig.java

@@ -0,0 +1,87 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 推荐分类配置对象 dkh_recommend_category_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_recommend_category_config")
+public class DkhRecommendCategoryConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 分类名称 (如: 猜你喜欢, 防暑降温)
+     */
+    private String name;
+
+    /**
+     * 分类图标URL (36*36px PNG)
+     */
+    private String iconUrl;
+
+    /**
+     * 数据类型: select=商品自选, category=分类映射
+     */
+    private String dataType;
+
+    /**
+     * 映射分类ID路径 (用于级联选择器回显)
+     */
+    private String categoryPath;
+
+    /**
+     * 映射分类名称路径 (显示用: 文具耗材 > 打印耗材)
+     */
+    private String categoryLabel;
+
+    /**
+     * 自选商品ID集合 (JSON数组格式: [1001, 1002])
+     */
+    private String selectedProductIds;
+
+    /**
+     * 排序权重 (数值越小越靠前)
+     */
+    private Long sortOrder;
+
+    /**
+     * 启用状态 (1-启用, 0-禁用)
+     */
+    private Long status;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 57 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhRecommendThemeConfig.java

@@ -0,0 +1,57 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 推荐全局主题配置对象 dkh_recommend_theme_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_recommend_theme_config")
+public class DkhRecommendThemeConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 主题选中色调 (如: #e60012)
+     */
+    private String themeColor;
+
+    /**
+     * 选中背景透明度 (范围 0.00 - 1.00)
+     */
+    private Long bgOpacity;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 89 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/DkhScenarioConfig.java

@@ -0,0 +1,89 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+
+import java.io.Serial;
+
+/**
+ * 场景解决方案配置对象 dkh_scenario_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_scenario_config")
+public class DkhScenarioConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 模块启用状态:1-开启,0-关闭
+     */
+    private Long status;
+
+    /**
+     * 场景大图背景地址
+     */
+    private String bgImage;
+
+    /**
+     * 场景主标题
+     */
+    private String mainTitle;
+
+    /**
+     * 主标题字体颜色
+     */
+    private String mainTitleColor;
+
+    /**
+     * 场景副标题
+     */
+    private String subTitle;
+
+    /**
+     * 副标题字体颜色
+     */
+    private String subTitleColor;
+
+    /**
+     * 全局跳转链接
+     */
+    private String jumpLink;
+
+    /**
+     * 子方案卡片配置列表(包含图片和链接,数组顺序即为展示顺序)
+     */
+    private String subCardsJson;
+
+    /**
+     * 删除标志(0代表存在,2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 74 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhAdConfigBo.java

@@ -0,0 +1,74 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhAdConfig;
+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.*;
+
+/**
+ * 广告模块配置业务对象 dkh_ad_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhAdConfig.class, reverseConvertGenerate = false)
+public class DkhAdConfigBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 模块位置索引:0-采购场景, 1-合作品牌, 2-排行榜, 3-企业精选(大图), 4-重磅新品
+     */
+    private Long moduleIndex;
+
+    /**
+     * 主标题文本
+     */
+    private String mainTitle;
+
+    /**
+     * 主标题字体颜色
+     */
+    private String mainTitleColor;
+
+    /**
+     * 副标题文本
+     */
+    private String subTitle;
+
+    /**
+     * 副标题字体颜色
+     */
+    private String subTitleColor;
+
+    /**
+     * 副标题跳转链接 (支持外链)
+     */
+    private String subTitleLink;
+
+    /**
+     * 商品或品牌列表数据
+     */
+    private String itemsJson;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 64 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhCarouselConfigBo.java

@@ -0,0 +1,64 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhCarouselConfig;
+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.*;
+
+/**
+ * 企业轮播图配置业务对象 dkh_carousel_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhCarouselConfig.class, reverseConvertGenerate = false)
+public class DkhCarouselConfigBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 轮播图图片地址
+     */
+    private String imageUrl;
+
+    /**
+     * 点击跳转的目标链接地址
+     */
+    private String linkUrl;
+
+    /**
+     * 打开方式: _blank (新窗口), _self (当前窗口)
+     */
+    private String target;
+
+    /**
+     * 排序权重,数值越小越靠前
+     */
+    private Long sortOrder;
+
+    /**
+     * 状态: 1-启用, 0-禁用
+     */
+    private Long status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 64 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhCategoryMainBo.java

@@ -0,0 +1,64 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhCategoryMain;
+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.*;
+
+/**
+ * 分类设置主业务对象 dkh_category_main
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhCategoryMain.class, reverseConvertGenerate = false)
+public class DkhCategoryMainBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 一级菜单名称(如:办公电脑 / 办公打印)
+     */
+    private String name;
+
+    /**
+     * 标签设置列表 [{"name":"热销", "link":"..."}]
+     */
+    private String tagsJson;
+
+    /**
+     * 启用状态:1-开启,0-关闭
+     */
+    private Long status;
+
+    /**
+     * 右滑面板配置:主副标题及便签列表
+     */
+    private String panelConfigJson;
+
+    /**
+     * 远程商品分类表中同步过来的一级分类ID
+     */
+    private Long syncCategoryId;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 74 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhCategorySubBo.java

@@ -0,0 +1,74 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhCategorySub;
+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.*;
+
+/**
+ * 分类设置子菜单业务对象 dkh_category_sub
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhCategorySub.class, reverseConvertGenerate = false)
+public class DkhCategorySubBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 所属一级分类ID(关联 dkh_category_main.id)
+     */
+    private Long mainCategoryId;
+
+    /**
+     * 父级菜单ID(0代表是一级子菜单,即树的第二层)
+     */
+    private Long parentId;
+
+    /**
+     * 分类名称
+     */
+    private String name;
+
+    /**
+     * 当前层级深度(2=二级分类, 3=三级分类)
+     */
+    private Long level;
+
+    /**
+     * 排序权重(数值越小越靠前)
+     */
+    private Long sortOrder;
+
+    /**
+     * 启用状态:1-开启,0-关闭
+     */
+    private Long status;
+
+    /**
+     * 远程商品分类表中同步过来的分类ID
+     */
+    private Long syncCategoryId;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 59 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhHeaderMenuBo.java

@@ -0,0 +1,59 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhHeaderMenu;
+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.*;
+
+/**
+ * 顶部导航菜单配置业务对象 dkh_header_menu
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhHeaderMenu.class, reverseConvertGenerate = false)
+public class DkhHeaderMenuBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 菜单标题名称(如:公共采购)
+     */
+    private String title;
+
+    /**
+     * 跳转地址
+     */
+    private String linkUrl;
+
+    /**
+     * 排序权重(数值越小越靠前,支持拖拽排序)
+     */
+    private Long sortOrder;
+
+    /**
+     * 启用状态:1-启用,0-禁用
+     */
+    private Long status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 80 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhMallConfigBo.java

@@ -0,0 +1,80 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhMallConfig;
+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.*;
+
+/**
+ * 商城首页配置业务对象 dkh_mall_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhMallConfig.class, reverseConvertGenerate = false)
+public class DkhMallConfigBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于区分不同企业的配置
+     */
+    private Long customerId;
+
+    /**
+     * 主标题(如:优易慧采)
+     */
+    private String mainTitle;
+
+    /**
+     * 企业Logo图片地址
+     */
+    private String logoUrl;
+
+    /**
+     * 搜索框提示文字
+     */
+    private String searchPlaceholder;
+
+    /**
+     * 搜索热词列表
+     */
+    private String hotWords;
+
+    /**
+     * 右侧按钮文字(如:我的采购单)
+     */
+    private String btnText;
+
+    /**
+     * 主题色 HEX值
+     */
+    private String themeColor;
+
+    /**
+     * 状态:1启用 0禁用
+     */
+    private Long status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+    /*分类主题色*/
+    private String categoryThemeColor;
+
+    /*头部主题色*/
+    private String headerThemeColor;
+
+
+}

+ 79 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhRecommendCategoryConfigBo.java

@@ -0,0 +1,79 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhRecommendCategoryConfig;
+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.*;
+
+/**
+ * 推荐分类配置业务对象 dkh_recommend_category_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhRecommendCategoryConfig.class, reverseConvertGenerate = false)
+public class DkhRecommendCategoryConfigBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 分类名称 (如: 猜你喜欢, 防暑降温)
+     */
+    private String name;
+
+    /**
+     * 分类图标URL (36*36px PNG)
+     */
+    private String iconUrl;
+
+    /**
+     * 数据类型: select=商品自选, category=分类映射
+     */
+    private String dataType;
+
+    /**
+     * 映射分类ID路径 (用于级联选择器回显)
+     */
+    private String categoryPath;
+
+    /**
+     * 映射分类名称路径 (显示用: 文具耗材 > 打印耗材)
+     */
+    private String categoryLabel;
+
+    /**
+     * 自选商品ID集合 (JSON数组格式: [1001, 1002])
+     */
+    private String selectedProductIds;
+
+    /**
+     * 排序权重 (数值越小越靠前)
+     */
+    private Long sortOrder;
+
+    /**
+     * 启用状态 (1-启用, 0-禁用)
+     */
+    private Long status;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 49 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhRecommendThemeConfigBo.java

@@ -0,0 +1,49 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhRecommendThemeConfig;
+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.*;
+
+/**
+ * 推荐全局主题配置业务对象 dkh_recommend_theme_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhRecommendThemeConfig.class, reverseConvertGenerate = false)
+public class DkhRecommendThemeConfigBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 主题选中色调 (如: #e60012)
+     */
+    private String themeColor;
+
+    /**
+     * 选中背景透明度 (范围 0.00 - 1.00)
+     */
+    private Long bgOpacity;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 81 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/DkhScenarioConfigBo.java

@@ -0,0 +1,81 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.DkhScenarioConfig;
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import org.dromara.common.core.validate.AddGroup;
+import org.dromara.common.core.validate.EditGroup;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import jakarta.validation.constraints.*;
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+
+/**
+ * 场景解决方案配置业务对象 dkh_scenario_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhScenarioConfig.class, reverseConvertGenerate = false)
+public class DkhScenarioConfigBo extends BaseEntity {
+
+    /**
+     * 主键ID
+     */
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    private Long customerId;
+
+    /**
+     * 模块启用状态:1-开启,0-关闭
+     */
+    private Long status;
+
+    /**
+     * 场景大图背景地址
+     */
+    private String bgImage;
+
+    /**
+     * 场景主标题
+     */
+    private String mainTitle;
+
+    /**
+     * 主标题字体颜色
+     */
+    private String mainTitleColor;
+
+    /**
+     * 场景副标题
+     */
+    private String subTitle;
+
+    /**
+     * 副标题字体颜色
+     */
+    private String subTitleColor;
+
+    /**
+     * 全局跳转链接
+     */
+    private String jumpLink;
+
+    /**
+     * 子方案卡片配置列表(包含图片和链接,数组顺序即为展示顺序)
+     */
+    private String subCardsJson;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 92 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhAdConfigVo.java

@@ -0,0 +1,92 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.DkhAdConfig;
+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;
+
+
+
+/**
+ * 广告模块配置视图对象 dkh_ad_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhAdConfig.class)
+public class DkhAdConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 模块位置索引:0-采购场景, 1-合作品牌, 2-排行榜, 3-企业精选(大图), 4-重磅新品
+     */
+    @ExcelProperty(value = "模块位置索引:0-采购场景, 1-合作品牌, 2-排行榜, 3-企业精选(大图), 4-重磅新品")
+    private Long moduleIndex;
+
+    /**
+     * 主标题文本
+     */
+    @ExcelProperty(value = "主标题文本")
+    private String mainTitle;
+
+    /**
+     * 主标题字体颜色
+     */
+    @ExcelProperty(value = "主标题字体颜色")
+    private String mainTitleColor;
+
+    /**
+     * 副标题文本
+     */
+    @ExcelProperty(value = "副标题文本")
+    private String subTitle;
+
+    /**
+     * 副标题字体颜色
+     */
+    @ExcelProperty(value = "副标题字体颜色")
+    private String subTitleColor;
+
+    /**
+     * 副标题跳转链接 (支持外链)
+     */
+    @ExcelProperty(value = "副标题跳转链接 (支持外链)")
+    private String subTitleLink;
+
+    /**
+     * 商品或品牌列表数据
+     */
+    @ExcelProperty(value = "商品或品牌列表数据")
+    private String itemsJson;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 80 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhCarouselConfigVo.java

@@ -0,0 +1,80 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.DkhCarouselConfig;
+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;
+
+
+
+/**
+ * 企业轮播图配置视图对象 dkh_carousel_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhCarouselConfig.class)
+public class DkhCarouselConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 轮播图图片地址
+     */
+    @ExcelProperty(value = "轮播图图片地址")
+    private String imageUrl;
+
+    /**
+     * 点击跳转的目标链接地址
+     */
+    @ExcelProperty(value = "点击跳转的目标链接地址")
+    private String linkUrl;
+
+    /**
+     * 打开方式: _blank (新窗口), _self (当前窗口)
+     */
+    @ExcelProperty(value = "打开方式: _blank (新窗口), _self (当前窗口)")
+    private String target;
+
+    /**
+     * 排序权重,数值越小越靠前
+     */
+    @ExcelProperty(value = "排序权重,数值越小越靠前")
+    private Long sortOrder;
+
+    /**
+     * 状态: 1-启用, 0-禁用
+     */
+    @ExcelProperty(value = "状态: 1-启用, 0-禁用")
+    private Long status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 96 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhCategoryMainVo.java

@@ -0,0 +1,96 @@
+package org.dromara.mall.domain.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import org.dromara.mall.domain.DkhCategoryMain;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.List;
+import java.util.Map;
+
+
+/**
+ * 分类设置主视图对象 dkh_category_main
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhCategoryMain.class)
+public class DkhCategoryMainVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 一级菜单名称(如:办公电脑 / 办公打印)
+     */
+    @ExcelProperty(value = "一级菜单名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:办公电脑,/=,办=公打印")
+    private String name;
+
+    /**
+     * 标签设置列表 [{"name":"热销", "link":"..."}]
+     */
+    private String tagsJson;
+
+    /**
+     * 启用状态:1-开启,0-关闭
+     */
+    @ExcelProperty(value = "启用状态:1-开启,0-关闭")
+    private Long status;
+
+    /**
+     * 右滑面板配置:主副标题及便签列表
+     */
+    @ExcelProperty(value = "右滑面板配置:主副标题及便签列表")
+    private String panelConfigJson;
+
+    /**
+     * 远程商品分类表中同步过来的一级分类ID
+     */
+    @ExcelProperty(value = "远程商品分类表中同步过来的一级分类ID")
+    private Long syncCategoryId;
+
+    /**
+     * 标签列表(解析后)
+     */
+    private List<Map<String, Object>> tags;
+
+    /**
+     * 子菜单列表(解析后,树形结构)
+     */
+    private List<Map<String, Object>> subMenus;
+
+    /**
+     * 面板数据(解析后)
+     */
+    private Map<String, Object> panelData;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    private String categoryThemeColor;
+
+}

+ 95 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhCategorySubVo.java

@@ -0,0 +1,95 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.DkhCategorySub;
+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;
+
+
+
+/**
+ * 分类设置子菜单视图对象 dkh_category_sub
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhCategorySub.class)
+public class DkhCategorySubVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 所属一级分类ID(关联 dkh_category_main.id)
+     */
+    @ExcelProperty(value = "所属一级分类ID", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "关=联,d=kh_category_main.id")
+    private Long mainCategoryId;
+
+    /**
+     * 父级菜单ID(0代表是一级子菜单,即树的第二层)
+     */
+    @ExcelProperty(value = "父级菜单ID", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=代表是一级子菜单,即树的第二层")
+    private Long parentId;
+
+    /**
+     * 分类名称
+     */
+    @ExcelProperty(value = "分类名称")
+    private String name;
+
+    /**
+     * 当前层级深度(2=二级分类, 3=三级分类)
+     */
+    @ExcelProperty(value = "当前层级深度", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "2==二级分类,,3==三级分类")
+    private Long level;
+
+    /**
+     * 排序权重(数值越小越靠前)
+     */
+    @ExcelProperty(value = "排序权重", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "数=值越小越靠前")
+    private Long sortOrder;
+
+    /**
+     * 启用状态:1-开启,0-关闭
+     */
+    @ExcelProperty(value = "启用状态:1-开启,0-关闭")
+    private Long status;
+
+    /**
+     * 远程商品分类表中同步过来的分类ID
+     */
+    private Long syncCategoryId;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 77 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhHeaderMenuVo.java

@@ -0,0 +1,77 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.DkhHeaderMenu;
+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;
+
+
+
+/**
+ * 顶部导航菜单配置视图对象 dkh_header_menu
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhHeaderMenu.class)
+public class DkhHeaderMenuVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 菜单标题名称(如:公共采购)
+     */
+    @ExcelProperty(value = "菜单标题名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:公共采购")
+    private String title;
+
+    /**
+     * 跳转地址
+     */
+    @ExcelProperty(value = "跳转地址")
+    private String linkUrl;
+
+    /**
+     * 排序权重(数值越小越靠前,支持拖拽排序)
+     */
+    @ExcelProperty(value = "排序权重", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "数=值越小越靠前,支持拖拽排序")
+    private Long sortOrder;
+
+    /**
+     * 启用状态:1-启用,0-禁用
+     */
+    @ExcelProperty(value = "启用状态:1-启用,0-禁用")
+    private Long status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    /*头部主题色*/
+    private String headerThemeColor;
+}

+ 99 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhMallConfigVo.java

@@ -0,0 +1,99 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.DkhMallConfig;
+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;
+
+
+
+/**
+ * 商城首页配置视图对象 dkh_mall_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhMallConfig.class)
+public class DkhMallConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于区分不同企业的配置
+     */
+    @ExcelProperty(value = "客户ID,用于区分不同企业的配置")
+    private Long customerId;
+
+    /**
+     * 主标题(如:优易慧采)
+     */
+    @ExcelProperty(value = "主标题", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:优易慧采")
+    private String mainTitle;
+
+    /**
+     * 企业Logo图片地址
+     */
+    @ExcelProperty(value = "企业Logo图片地址")
+    private String logoUrl;
+
+    /**
+     * 搜索框提示文字
+     */
+    @ExcelProperty(value = "搜索框提示文字")
+    private String searchPlaceholder;
+
+    /**
+     * 搜索热词列表
+     */
+    @ExcelProperty(value = "搜索热词列表")
+    private String hotWords;
+
+    /**
+     * 右侧按钮文字(如:我的采购单)
+     */
+    @ExcelProperty(value = "右侧按钮文字", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "如=:我的采购单")
+    private String btnText;
+
+    /**
+     * 主题色 HEX值
+     */
+    @ExcelProperty(value = "主题色 HEX值")
+    private String themeColor;
+
+    /**
+     * 状态:1启用 0禁用
+     */
+    @ExcelProperty(value = "状态:1启用 0禁用")
+    private Long status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    /*分类主题色*/
+    private String categoryThemeColor;
+
+    /*头部主题色*/
+    private String headerThemeColor;
+
+}

+ 94 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhRecommendCategoryConfigVo.java

@@ -0,0 +1,94 @@
+package org.dromara.mall.domain.vo;
+
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+import org.dromara.mall.domain.DkhRecommendCategoryConfig;
+
+import java.io.Serial;
+import java.io.Serializable;
+
+
+/**
+ * 推荐分类配置视图对象 dkh_recommend_category_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhRecommendCategoryConfig.class)
+public class DkhRecommendCategoryConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 分类名称 (如: 猜你喜欢, 防暑降温)
+     */
+    @ExcelProperty(value = "分类名称 (如: 猜你喜欢, 防暑降温)")
+    private String name;
+
+    /**
+     * 分类图标URL (36*36px PNG)
+     */
+    @ExcelProperty(value = "分类图标URL (36*36px PNG)")
+    private String iconUrl;
+
+    /**
+     * 数据类型: select=商品自选, category=分类映射
+     */
+    @ExcelProperty(value = "数据类型: select=商品自选, category=分类映射")
+    private String dataType;
+
+    /**
+     * 映射分类ID路径 (用于级联选择器回显)
+     */
+    @ExcelProperty(value = "映射分类ID路径 (用于级联选择器回显)")
+    private String categoryPath;
+
+    /**
+     * 映射分类名称路径 (显示用: 文具耗材 > 打印耗材)
+     */
+    @ExcelProperty(value = "映射分类名称路径 (显示用: 文具耗材 > 打印耗材)")
+    private String categoryLabel;
+
+    /**
+     * 自选商品ID集合 (JSON数组格式: [1001, 1002])
+     */
+    @ExcelProperty(value = "自选商品ID集合 (JSON数组格式: [1001, 1002])")
+    private String selectedProductIds;
+
+    /**
+     * 排序权重 (数值越小越靠前)
+     */
+    @ExcelProperty(value = "排序权重 (数值越小越靠前)")
+    private Long sortOrder;
+
+    /**
+     * 启用状态 (1-启用, 0-禁用)
+     */
+    @ExcelProperty(value = "启用状态 (1-启用, 0-禁用)")
+    private Long status;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 62 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhRecommendThemeConfigVo.java

@@ -0,0 +1,62 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.DkhRecommendThemeConfig;
+import cn.idev.excel.annotation.ExcelIgnoreUnannotated;
+import cn.idev.excel.annotation.ExcelProperty;
+import org.dromara.common.excel.annotation.ExcelDictFormat;
+import org.dromara.common.excel.convert.ExcelDictConvert;
+import io.github.linpeilie.annotations.AutoMapper;
+import lombok.Data;
+
+import java.io.Serial;
+import java.io.Serializable;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 推荐全局主题配置视图对象 dkh_recommend_theme_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhRecommendThemeConfig.class)
+public class DkhRecommendThemeConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 主题选中色调 (如: #e60012)
+     */
+    @ExcelProperty(value = "主题选中色调 (如: #e60012)")
+    private String themeColor;
+
+    /**
+     * 选中背景透明度 (范围 0.00 - 1.00)
+     */
+    @ExcelProperty(value = "选中背景透明度 (范围 0.00 - 1.00)")
+    private Long bgOpacity;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+    List<DkhRecommendCategoryConfigVo> categoryConfigList;
+}

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/DkhScenarioConfigVo.java

@@ -0,0 +1,106 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.common.translation.annotation.Translation;
+import org.dromara.common.translation.constant.TransConstant;
+import org.dromara.mall.domain.DkhScenarioConfig;
+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;
+
+
+
+/**
+ * 场景解决方案配置视图对象 dkh_scenario_config
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = DkhScenarioConfig.class)
+public class DkhScenarioConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键ID
+     */
+    @ExcelProperty(value = "主键ID")
+    private Long id;
+
+    /**
+     * 客户ID,用于数据隔离
+     */
+    @ExcelProperty(value = "客户ID,用于数据隔离")
+    private Long customerId;
+
+    /**
+     * 模块启用状态:1-开启,0-关闭
+     */
+    @ExcelProperty(value = "模块启用状态:1-开启,0-关闭")
+    private Long status;
+
+    /**
+     * 场景大图背景地址
+     */
+    @ExcelProperty(value = "场景大图背景地址")
+    private String bgImage;
+
+    /**
+     * 场景大图背景地址Url
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "bgImage")
+    private String bgImageUrl;
+    /**
+     * 场景主标题
+     */
+    @ExcelProperty(value = "场景主标题")
+    private String mainTitle;
+
+    /**
+     * 主标题字体颜色
+     */
+    @ExcelProperty(value = "主标题字体颜色")
+    private String mainTitleColor;
+
+    /**
+     * 场景副标题
+     */
+    @ExcelProperty(value = "场景副标题")
+    private String subTitle;
+
+    /**
+     * 副标题字体颜色
+     */
+    @ExcelProperty(value = "副标题字体颜色")
+    private String subTitleColor;
+
+    /**
+     * 全局跳转链接
+     */
+    @ExcelProperty(value = "全局跳转链接")
+    private String jumpLink;
+
+    /**
+     * 子方案卡片配置列表(包含图片和链接,数组顺序即为展示顺序)
+     */
+    @ExcelProperty(value = "子方案卡片配置列表", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "包=含图片和链接,数组顺序即为展示顺序")
+    private String subCardsJson;
+
+    /**
+     * 备注
+     */
+    @ExcelProperty(value = "备注")
+    private String remark;
+
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhAdConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhAdConfig;
+import org.dromara.mall.domain.vo.DkhAdConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 广告模块配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhAdConfigMapper extends BaseMapperPlus<DkhAdConfig, DkhAdConfigVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhCarouselConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhCarouselConfig;
+import org.dromara.mall.domain.vo.DkhCarouselConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 企业轮播图配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhCarouselConfigMapper extends BaseMapperPlus<DkhCarouselConfig, DkhCarouselConfigVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhCategoryMainMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhCategoryMain;
+import org.dromara.mall.domain.vo.DkhCategoryMainVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 分类设置主Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhCategoryMainMapper extends BaseMapperPlus<DkhCategoryMain, DkhCategoryMainVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhCategorySubMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhCategorySub;
+import org.dromara.mall.domain.vo.DkhCategorySubVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 分类设置子菜单Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhCategorySubMapper extends BaseMapperPlus<DkhCategorySub, DkhCategorySubVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhHeaderMenuMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhHeaderMenu;
+import org.dromara.mall.domain.vo.DkhHeaderMenuVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 顶部导航菜单配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhHeaderMenuMapper extends BaseMapperPlus<DkhHeaderMenu, DkhHeaderMenuVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhMallConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhMallConfig;
+import org.dromara.mall.domain.vo.DkhMallConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 商城首页配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhMallConfigMapper extends BaseMapperPlus<DkhMallConfig, DkhMallConfigVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhRecommendCategoryConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhRecommendCategoryConfig;
+import org.dromara.mall.domain.vo.DkhRecommendCategoryConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 推荐分类配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhRecommendCategoryConfigMapper extends BaseMapperPlus<DkhRecommendCategoryConfig, DkhRecommendCategoryConfigVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhRecommendThemeConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhRecommendThemeConfig;
+import org.dromara.mall.domain.vo.DkhRecommendThemeConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 推荐全局主题配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhRecommendThemeConfigMapper extends BaseMapperPlus<DkhRecommendThemeConfig, DkhRecommendThemeConfigVo> {
+
+}

+ 15 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/DkhScenarioConfigMapper.java

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.DkhScenarioConfig;
+import org.dromara.mall.domain.vo.DkhScenarioConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 场景解决方案配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface DkhScenarioConfigMapper extends BaseMapperPlus<DkhScenarioConfig, DkhScenarioConfigVo> {
+
+}

+ 70 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhAdConfigService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhAdConfig;
+import org.dromara.mall.domain.vo.DkhAdConfigVo;
+import org.dromara.mall.domain.bo.DkhAdConfigBo;
+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-06-02
+ */
+public interface IDkhAdConfigService extends IService<DkhAdConfig>{
+
+    /**
+     * 查询广告模块配置
+     *
+     * @param id 主键
+     * @return 广告模块配置
+     */
+    DkhAdConfigVo queryById(Long id);
+
+    /**
+     * 分页查询广告模块配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 广告模块配置分页列表
+     */
+    TableDataInfo<DkhAdConfigVo> queryPageList(DkhAdConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的广告模块配置列表
+     *
+     * @param bo 查询条件
+     * @return 广告模块配置列表
+     */
+    List<DkhAdConfigVo> queryList(DkhAdConfigBo bo);
+
+    /**
+     * 新增广告模块配置
+     *
+     * @param bo 广告模块配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhAdConfigBo bo);
+
+    /**
+     * 修改广告模块配置
+     *
+     * @param bo 广告模块配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhAdConfigBo bo);
+
+    /**
+     * 校验并批量删除广告模块配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 78 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhCarouselConfigService.java

@@ -0,0 +1,78 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhCarouselConfig;
+import org.dromara.mall.domain.vo.DkhCarouselConfigVo;
+import org.dromara.mall.domain.bo.DkhCarouselConfigBo;
+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-06-02
+ */
+public interface IDkhCarouselConfigService extends IService<DkhCarouselConfig>{
+
+    /**
+     * 查询企业轮播图配置
+     *
+     * @param id 主键
+     * @return 企业轮播图配置
+     */
+    DkhCarouselConfigVo queryById(Long id);
+
+    /**
+     * 分页查询企业轮播图配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 企业轮播图配置分页列表
+     */
+    TableDataInfo<DkhCarouselConfigVo> queryPageList(DkhCarouselConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的企业轮播图配置列表
+     *
+     * @param bo 查询条件
+     * @return 企业轮播图配置列表
+     */
+    List<DkhCarouselConfigVo> queryList(DkhCarouselConfigBo bo);
+
+    /**
+     * 新增企业轮播图配置
+     *
+     * @param bo 企业轮播图配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhCarouselConfigBo bo);
+
+    /**
+     * 修改企业轮播图配置
+     *
+     * @param bo 企业轮播图配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhCarouselConfigBo bo);
+
+    /**
+     * 校验并批量删除企业轮播图配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 状态修改
+     *
+     * @param bo 包含id和status
+     * @return 是否修改成功
+     */
+    Boolean updateStatus(DkhCarouselConfigBo bo);
+}

+ 78 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhCategoryMainService.java

@@ -0,0 +1,78 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhCategoryMain;
+import org.dromara.mall.domain.vo.DkhCategoryMainVo;
+import org.dromara.mall.domain.bo.DkhCategoryMainBo;
+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-06-02
+ */
+public interface IDkhCategoryMainService extends IService<DkhCategoryMain>{
+
+    /**
+     * 查询分类设置主
+     *
+     * @param id 主键
+     * @return 分类设置主
+     */
+    DkhCategoryMainVo queryById(Long id);
+
+    /**
+     * 分页查询分类设置主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 分类设置主分页列表
+     */
+    TableDataInfo<DkhCategoryMainVo> queryPageList(DkhCategoryMainBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的分类设置主列表
+     *
+     * @param bo 查询条件
+     * @return 分类设置主列表
+     */
+    List<DkhCategoryMainVo> queryList(DkhCategoryMainBo bo);
+
+    /**
+     * 新增分类设置主
+     *
+     * @param bo 分类设置主
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhCategoryMainBo bo);
+
+    /**
+     * 修改分类设置主
+     *
+     * @param bo 分类设置主
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhCategoryMainBo bo);
+
+    /**
+     * 修改状态
+     *
+     * @param bo 包含 id 和 status
+     * @return 是否修改成功
+     */
+    Boolean updateStatus(DkhCategoryMainBo bo);
+
+    /**
+     * 校验并批量删除分类设置主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 70 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhCategorySubService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhCategorySub;
+import org.dromara.mall.domain.vo.DkhCategorySubVo;
+import org.dromara.mall.domain.bo.DkhCategorySubBo;
+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-06-02
+ */
+public interface IDkhCategorySubService extends IService<DkhCategorySub>{
+
+    /**
+     * 查询分类设置子菜单
+     *
+     * @param id 主键
+     * @return 分类设置子菜单
+     */
+    DkhCategorySubVo queryById(Long id);
+
+    /**
+     * 分页查询分类设置子菜单列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 分类设置子菜单分页列表
+     */
+    TableDataInfo<DkhCategorySubVo> queryPageList(DkhCategorySubBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的分类设置子菜单列表
+     *
+     * @param bo 查询条件
+     * @return 分类设置子菜单列表
+     */
+    List<DkhCategorySubVo> queryList(DkhCategorySubBo bo);
+
+    /**
+     * 新增分类设置子菜单
+     *
+     * @param bo 分类设置子菜单
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhCategorySubBo bo);
+
+    /**
+     * 修改分类设置子菜单
+     *
+     * @param bo 分类设置子菜单
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhCategorySubBo bo);
+
+    /**
+     * 校验并批量删除分类设置子菜单信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 78 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhHeaderMenuService.java

@@ -0,0 +1,78 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhHeaderMenu;
+import org.dromara.mall.domain.vo.DkhHeaderMenuVo;
+import org.dromara.mall.domain.bo.DkhHeaderMenuBo;
+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-06-02
+ */
+public interface IDkhHeaderMenuService extends IService<DkhHeaderMenu>{
+
+    /**
+     * 查询顶部导航菜单配置
+     *
+     * @param id 主键
+     * @return 顶部导航菜单配置
+     */
+    DkhHeaderMenuVo queryById(Long id);
+
+    /**
+     * 分页查询顶部导航菜单配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 顶部导航菜单配置分页列表
+     */
+    TableDataInfo<DkhHeaderMenuVo> queryPageList(DkhHeaderMenuBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的顶部导航菜单配置列表
+     *
+     * @param bo 查询条件
+     * @return 顶部导航菜单配置列表
+     */
+    List<DkhHeaderMenuVo> queryList(DkhHeaderMenuBo bo);
+
+    /**
+     * 新增顶部导航菜单配置
+     *
+     * @param bo 顶部导航菜单配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhHeaderMenuBo bo);
+
+    /**
+     * 修改顶部导航菜单配置
+     *
+     * @param bo 顶部导航菜单配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhHeaderMenuBo bo);
+
+    /**
+     * 校验并批量删除顶部导航菜单配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 状态修改
+     *
+     * @param bo 包含id和status
+     * @return 是否修改成功
+     */
+    Boolean updateStatus(DkhHeaderMenuBo bo);
+}

+ 78 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhMallConfigService.java

@@ -0,0 +1,78 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhMallConfig;
+import org.dromara.mall.domain.vo.DkhMallConfigVo;
+import org.dromara.mall.domain.bo.DkhMallConfigBo;
+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-06-02
+ */
+public interface IDkhMallConfigService extends IService<DkhMallConfig>{
+
+    /**
+     * 查询商城首页配置
+     *
+     * @param id 主键
+     * @return 商城首页配置
+     */
+    DkhMallConfigVo queryById(Long id);
+
+    /**
+     * 分页查询商城首页配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 商城首页配置分页列表
+     */
+    TableDataInfo<DkhMallConfigVo> queryPageList(DkhMallConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的商城首页配置列表
+     *
+     * @param bo 查询条件
+     * @return 商城首页配置列表
+     */
+    List<DkhMallConfigVo> queryList(DkhMallConfigBo bo);
+
+    /**
+     * 新增商城首页配置
+     *
+     * @param bo 商城首页配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhMallConfigBo bo);
+
+    /**
+     * 修改商城首页配置
+     *
+     * @param bo 商城首页配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhMallConfigBo bo);
+
+    /**
+     * 校验并批量删除商城首页配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 获取当前客户的商城首页配置
+     *
+     * @param customerId 客户ID
+     * @return 商城首页配置
+     */
+    DkhMallConfigVo getCurrentMallConfig(Long customerId);
+}

+ 78 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhRecommendCategoryConfigService.java

@@ -0,0 +1,78 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhRecommendCategoryConfig;
+import org.dromara.mall.domain.vo.DkhRecommendCategoryConfigVo;
+import org.dromara.mall.domain.bo.DkhRecommendCategoryConfigBo;
+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-06-02
+ */
+public interface IDkhRecommendCategoryConfigService extends IService<DkhRecommendCategoryConfig>{
+
+    /**
+     * 查询推荐分类配置
+     *
+     * @param id 主键
+     * @return 推荐分类配置
+     */
+    DkhRecommendCategoryConfigVo queryById(Long id);
+
+    /**
+     * 分页查询推荐分类配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 推荐分类配置分页列表
+     */
+    TableDataInfo<DkhRecommendCategoryConfigVo> queryPageList(DkhRecommendCategoryConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的推荐分类配置列表
+     *
+     * @param bo 查询条件
+     * @return 推荐分类配置列表
+     */
+    List<DkhRecommendCategoryConfigVo> queryList(DkhRecommendCategoryConfigBo bo);
+
+    /**
+     * 新增推荐分类配置
+     *
+     * @param bo 推荐分类配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhRecommendCategoryConfigBo bo);
+
+    /**
+     * 修改推荐分类配置
+     *
+     * @param bo 推荐分类配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhRecommendCategoryConfigBo bo);
+
+    /**
+     * 校验并批量删除推荐分类配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 状态修改
+     *
+     * @param bo 包含id和status
+     * @return 是否修改成功
+     */
+    Boolean updateStatus(DkhRecommendCategoryConfigBo bo);
+}

+ 72 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhRecommendThemeConfigService.java

@@ -0,0 +1,72 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhRecommendThemeConfig;
+import org.dromara.mall.domain.bo.DkhRecommendThemeConfigBo;
+import org.dromara.mall.domain.vo.DkhRecommendThemeConfigVo;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 推荐全局主题配置Service接口
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+public interface IDkhRecommendThemeConfigService extends IService<DkhRecommendThemeConfig> {
+
+    /**
+     * 查询推荐全局主题配置
+     *
+     * @param id 主键
+     * @return 推荐全局主题配置
+     */
+    DkhRecommendThemeConfigVo queryById(Long id);
+
+    /**
+     * 分页查询推荐全局主题配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 推荐全局主题配置分页列表
+     */
+    TableDataInfo<DkhRecommendThemeConfigVo> queryPageList(DkhRecommendThemeConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的推荐全局主题配置列表
+     *
+     * @param bo 查询条件
+     * @return 推荐全局主题配置列表
+     */
+    List<DkhRecommendThemeConfigVo> queryList(DkhRecommendThemeConfigBo bo);
+
+    /**
+     * 新增推荐全局主题配置
+     *
+     * @param bo 推荐全局主题配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhRecommendThemeConfigBo bo);
+
+    /**
+     * 修改推荐全局主题配置
+     *
+     * @param bo 推荐全局主题配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhRecommendThemeConfigBo bo);
+
+    /**
+     * 校验并批量删除推荐全局主题配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    DkhRecommendThemeConfigVo getCurrentRecommendThemeConfig(Long customerId);
+}

+ 70 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/IDkhScenarioConfigService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.DkhScenarioConfig;
+import org.dromara.mall.domain.vo.DkhScenarioConfigVo;
+import org.dromara.mall.domain.bo.DkhScenarioConfigBo;
+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-06-02
+ */
+public interface IDkhScenarioConfigService extends IService<DkhScenarioConfig>{
+
+    /**
+     * 查询场景解决方案配置
+     *
+     * @param id 主键
+     * @return 场景解决方案配置
+     */
+    DkhScenarioConfigVo queryById(Long id);
+
+    /**
+     * 分页查询场景解决方案配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 场景解决方案配置分页列表
+     */
+    TableDataInfo<DkhScenarioConfigVo> queryPageList(DkhScenarioConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的场景解决方案配置列表
+     *
+     * @param bo 查询条件
+     * @return 场景解决方案配置列表
+     */
+    List<DkhScenarioConfigVo> queryList(DkhScenarioConfigBo bo);
+
+    /**
+     * 新增场景解决方案配置
+     *
+     * @param bo 场景解决方案配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(DkhScenarioConfigBo bo);
+
+    /**
+     * 修改场景解决方案配置
+     *
+     * @param bo 场景解决方案配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(DkhScenarioConfigBo bo);
+
+    /**
+     * 校验并批量删除场景解决方案配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+}

+ 141 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhAdConfigServiceImpl.java

@@ -0,0 +1,141 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhAdConfig;
+import org.dromara.mall.domain.bo.DkhAdConfigBo;
+import org.dromara.mall.domain.vo.DkhAdConfigVo;
+import org.dromara.mall.mapper.DkhAdConfigMapper;
+import org.dromara.mall.service.IDkhAdConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 广告模块配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhAdConfigServiceImpl extends ServiceImpl<DkhAdConfigMapper, DkhAdConfig> implements IDkhAdConfigService {
+
+    private final DkhAdConfigMapper baseMapper;
+
+    /**
+     * 查询广告模块配置
+     *
+     * @param id 主键
+     * @return 广告模块配置
+     */
+    @Override
+    public DkhAdConfigVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询广告模块配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 广告模块配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhAdConfigVo> queryPageList(DkhAdConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhAdConfig> lqw = buildQueryWrapper(bo);
+        Page<DkhAdConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的广告模块配置列表
+     *
+     * @param bo 查询条件
+     * @return 广告模块配置列表
+     */
+    @Override
+    public List<DkhAdConfigVo> queryList(DkhAdConfigBo bo) {
+        LambdaQueryWrapper<DkhAdConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhAdConfig> buildQueryWrapper(DkhAdConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhAdConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhAdConfig::getId);
+        lqw.eq(bo.getCustomerId() != null, DkhAdConfig::getCustomerId, bo.getCustomerId());
+        lqw.eq(bo.getModuleIndex() != null, DkhAdConfig::getModuleIndex, bo.getModuleIndex());
+        lqw.eq(StringUtils.isNotBlank(bo.getMainTitle()), DkhAdConfig::getMainTitle, bo.getMainTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getMainTitleColor()), DkhAdConfig::getMainTitleColor, bo.getMainTitleColor());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubTitle()), DkhAdConfig::getSubTitle, bo.getSubTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubTitleColor()), DkhAdConfig::getSubTitleColor, bo.getSubTitleColor());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubTitleLink()), DkhAdConfig::getSubTitleLink, bo.getSubTitleLink());
+        lqw.eq(StringUtils.isNotBlank(bo.getItemsJson()), DkhAdConfig::getItemsJson, bo.getItemsJson());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhAdConfig::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增广告模块配置
+     *
+     * @param bo 广告模块配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhAdConfigBo bo) {
+        DkhAdConfig add = MapstructUtils.convert(bo, DkhAdConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改广告模块配置
+     *
+     * @param bo 广告模块配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhAdConfigBo bo) {
+        DkhAdConfig update = MapstructUtils.convert(bo, DkhAdConfig.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhAdConfig entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除广告模块配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 153 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhCarouselConfigServiceImpl.java

@@ -0,0 +1,153 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhCarouselConfig;
+import org.dromara.mall.domain.bo.DkhCarouselConfigBo;
+import org.dromara.mall.domain.vo.DkhCarouselConfigVo;
+import org.dromara.mall.mapper.DkhCarouselConfigMapper;
+import org.dromara.mall.service.IDkhCarouselConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 企业轮播图配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhCarouselConfigServiceImpl extends ServiceImpl<DkhCarouselConfigMapper, DkhCarouselConfig> implements IDkhCarouselConfigService {
+
+    private final DkhCarouselConfigMapper baseMapper;
+
+    /**
+     * 查询企业轮播图配置
+     *
+     * @param id 主键
+     * @return 企业轮播图配置
+     */
+    @Override
+    public DkhCarouselConfigVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询企业轮播图配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 企业轮播图配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhCarouselConfigVo> queryPageList(DkhCarouselConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhCarouselConfig> lqw = buildQueryWrapper(bo);
+        Page<DkhCarouselConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的企业轮播图配置列表
+     *
+     * @param bo 查询条件
+     * @return 企业轮播图配置列表
+     */
+    @Override
+    public List<DkhCarouselConfigVo> queryList(DkhCarouselConfigBo bo) {
+        LambdaQueryWrapper<DkhCarouselConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhCarouselConfig> buildQueryWrapper(DkhCarouselConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhCarouselConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhCarouselConfig::getSortOrder);
+        lqw.eq(bo.getCustomerId() != null, DkhCarouselConfig::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getImageUrl()), DkhCarouselConfig::getImageUrl, bo.getImageUrl());
+        lqw.eq(StringUtils.isNotBlank(bo.getLinkUrl()), DkhCarouselConfig::getLinkUrl, bo.getLinkUrl());
+        lqw.eq(StringUtils.isNotBlank(bo.getTarget()), DkhCarouselConfig::getTarget, bo.getTarget());
+        lqw.eq(bo.getSortOrder() != null, DkhCarouselConfig::getSortOrder, bo.getSortOrder());
+        lqw.eq(bo.getStatus() != null, DkhCarouselConfig::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhCarouselConfig::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增企业轮播图配置
+     *
+     * @param bo 企业轮播图配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhCarouselConfigBo bo) {
+        DkhCarouselConfig add = MapstructUtils.convert(bo, DkhCarouselConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改企业轮播图配置
+     *
+     * @param bo 企业轮播图配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhCarouselConfigBo bo) {
+        DkhCarouselConfig update = MapstructUtils.convert(bo, DkhCarouselConfig.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhCarouselConfig entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除企业轮播图配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 状态修改
+     *
+     * @param bo 包含id和status
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateStatus(DkhCarouselConfigBo bo) {
+        DkhCarouselConfig update = new DkhCarouselConfig();
+        update.setId(bo.getId());
+        update.setStatus(bo.getStatus());
+        return baseMapper.updateById(update) > 0;
+    }
+}

+ 612 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhCategoryMainServiceImpl.java

@@ -0,0 +1,612 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.dubbo.config.annotation.DubboReference;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.ObjectUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhCategoryMain;
+import org.dromara.mall.domain.DkhCategorySub;
+import org.dromara.mall.domain.bo.DkhCategoryMainBo;
+import org.dromara.mall.domain.vo.DkhCategoryMainVo;
+import org.dromara.mall.domain.vo.DkhMallConfigVo;
+import org.dromara.mall.domain.vo.EpSearchConfigVo;
+import org.dromara.mall.mapper.DkhCategoryMainMapper;
+import org.dromara.mall.mapper.DkhCategorySubMapper;
+import org.dromara.mall.service.IDkhCategoryMainService;
+import org.dromara.mall.service.IDkhMallConfigService;
+import org.dromara.product.api.RemoteCategoryService;
+import org.dromara.product.api.domain.CategoryDto;
+import org.springframework.stereotype.Service;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 分类设置主Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhCategoryMainServiceImpl extends ServiceImpl<DkhCategoryMainMapper, DkhCategoryMain> implements IDkhCategoryMainService {
+
+    private final DkhCategoryMainMapper baseMapper;
+
+    private final DkhCategorySubMapper categorySubMapper;
+
+    private final IDkhMallConfigService dkhMallConfigService;
+
+    @DubboReference
+    private RemoteCategoryService remoteCategoryService;
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 查询分类设置主
+     *
+     * @param id 主键
+     * @return 分类设置主
+     */
+    @Override
+    public DkhCategoryMainVo queryById(Long id) {
+        DkhCategoryMainVo vo = baseMapper.selectVoById(id);
+        if (vo != null) {
+            fillParsedFields(vo);
+        }
+        return vo;
+    }
+
+    /**
+     * 分页查询分类设置主列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 分类设置主分页列表
+     */
+    @Override
+    public TableDataInfo<DkhCategoryMainVo> queryPageList(DkhCategoryMainBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhCategoryMain> lqw = buildQueryWrapper(bo);
+        Page<DkhCategoryMainVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        DkhMallConfigVo currentMallConfig =null;
+        if (ObjectUtils.isNotEmpty(bo.getCustomerId())){
+            currentMallConfig= dkhMallConfigService.getCurrentMallConfig(bo.getCustomerId());
+        }
+
+        for (DkhCategoryMainVo vo : result.getRecords()) {
+            fillParsedFields(vo);
+            if (ObjectUtils.isNotEmpty(currentMallConfig)){
+                vo.setCategoryThemeColor(currentMallConfig.getCategoryThemeColor());
+            }
+        }
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的分类设置主列表
+     *
+     * @param bo 查询条件
+     * @return 分类设置主列表
+     */
+    @Override
+    public List<DkhCategoryMainVo> queryList(DkhCategoryMainBo bo) {
+        LambdaQueryWrapper<DkhCategoryMain> lqw = buildQueryWrapper(bo);
+        List<DkhCategoryMainVo> list = baseMapper.selectVoList(lqw);
+        for (DkhCategoryMainVo vo : list) {
+            fillParsedFields(vo);
+        }
+        return list;
+    }
+
+    private LambdaQueryWrapper<DkhCategoryMain> buildQueryWrapper(DkhCategoryMainBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhCategoryMain> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhCategoryMain::getId);
+        lqw.eq(bo.getCustomerId() != null, DkhCategoryMain::getCustomerId, bo.getCustomerId());
+        lqw.like(StringUtils.isNotBlank(bo.getName()), DkhCategoryMain::getName, bo.getName());
+        lqw.eq(StringUtils.isNotBlank(bo.getTagsJson()), DkhCategoryMain::getTagsJson, bo.getTagsJson());
+        lqw.eq(bo.getStatus() != null, DkhCategoryMain::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPanelConfigJson()), DkhCategoryMain::getPanelConfigJson, bo.getPanelConfigJson());
+        lqw.eq(bo.getSyncCategoryId() != null, DkhCategoryMain::getSyncCategoryId, bo.getSyncCategoryId());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhCategoryMain::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增分类设置主
+     *
+     * @param bo 分类设置主
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhCategoryMainBo bo) {
+        DkhCategoryMain add = MapstructUtils.convert(bo, DkhCategoryMain.class);
+        validEntityBeforeSave(add);
+
+        // 先插入主表数据
+        boolean flag = baseMapper.insert(add) > 0;
+        if (!flag) {
+            return false;
+        }
+
+        // 解析 panelConfigJson 中的 subMenus,同步到远程商品分类表 + 本地 sub 表
+        try {
+            if (StringUtils.isNotBlank(bo.getPanelConfigJson())) {
+                JsonNode rootNode = objectMapper.readTree(bo.getPanelConfigJson());
+                JsonNode subMenus = rootNode.get("subMenus");
+
+                if (subMenus != null && subMenus.isArray()) {
+                    // ========== 1. 同步到远程商品分类表 ==========
+                    CategoryDto level1Dto = new CategoryDto();
+                    level1Dto.setCategoryName(bo.getName());
+                    level1Dto.setParentId(0L);
+                    level1Dto.setClassLevel(1L);
+                    level1Dto.setIsShow(1L);
+                    level1Dto.setSort(0L);
+                    level1Dto.setDataSource("youyi");
+                    level1Dto.setPlatform(4L);
+                    level1Dto.setAncestors("0");
+
+                    List<CategoryDto> level1List = new ArrayList<>();
+                    level1List.add(level1Dto);
+                    Long level1Id = remoteCategoryService.insertCategory(level1List);
+
+                    if (level1Id != null) {
+                        add.setSyncCategoryId(level1Id);
+                        baseMapper.updateById(add);
+
+                        String level1Ancestors = "0," + level1Id;
+
+                        if (subMenus.size() > 0) {
+                            for (JsonNode level2Node : subMenus) {
+                                // 远程:二级分类
+                                CategoryDto level2Dto = new CategoryDto();
+                                level2Dto.setCategoryName(level2Node.has("name") ? level2Node.get("name").asText() : null);
+                                level2Dto.setParentId(level1Id);
+                                level2Dto.setClassLevel(2L);
+                                level2Dto.setIsShow(level2Node.has("status") ? level2Node.get("status").asLong() : 1L);
+                                level2Dto.setSort(level2Node.has("sortOrder") ? level2Node.get("sortOrder").asLong() : 0L);
+                                level2Dto.setDataSource("youyi");
+                                level2Dto.setPlatform(4L);
+                                level2Dto.setAncestors(level1Ancestors);
+
+                                List<CategoryDto> level2List = new ArrayList<>();
+                                level2List.add(level2Dto);
+                                Long level2Id = remoteCategoryService.insertCategory(level2List);
+
+                                // ========== 2. 保存二级分类到本地 DkhCategorySub ==========
+                                DkhCategorySub level2Sub = new DkhCategorySub();
+                                level2Sub.setCustomerId(bo.getCustomerId());
+                                level2Sub.setMainCategoryId(add.getId());
+                                level2Sub.setParentId(0L);
+                                level2Sub.setName(level2Node.has("name") ? level2Node.get("name").asText() : null);
+                                level2Sub.setLevel(2L);
+                                level2Sub.setSortOrder(level2Node.has("sortOrder") ? level2Node.get("sortOrder").asLong() : 0L);
+                                level2Sub.setStatus(level2Node.has("status") ? level2Node.get("status").asLong() : 1L);
+                                level2Sub.setSyncCategoryId(level2Id);
+                                categorySubMapper.insert(level2Sub);
+
+                                // 处理三级分类
+                                JsonNode level3Nodes = level2Node.get("children");
+                                if (level3Nodes != null && level3Nodes.isArray() && !level3Nodes.isEmpty()) {
+                                    String level2Ancestors = level1Ancestors + "," + level2Id;
+
+                                    for (JsonNode level3Node : level3Nodes) {
+                                        // 远程:三级分类
+                                        CategoryDto level3Dto = new CategoryDto();
+                                        level3Dto.setCategoryName(level3Node.has("name") ? level3Node.get("name").asText() : null);
+                                        level3Dto.setParentId(level2Id);
+                                        level3Dto.setClassLevel(3L);
+                                        level3Dto.setIsShow(level3Node.has("status") ? level3Node.get("status").asLong() : 1L);
+                                        level3Dto.setSort(level3Node.has("sortOrder") ? level3Node.get("sortOrder").asLong() : 0L);
+                                        level3Dto.setDataSource("youyi");
+                                        level3Dto.setPlatform(4L);
+                                        level3Dto.setAncestors(level2Ancestors);
+
+                                        List<CategoryDto> level3List = new ArrayList<>();
+                                        level3List.add(level3Dto);
+                                        Long level3Id = remoteCategoryService.insertCategory(level3List);
+
+                                        // 本地:三级分类 → DkhCategorySub
+                                        DkhCategorySub level3Sub = new DkhCategorySub();
+                                        level3Sub.setCustomerId(bo.getCustomerId());
+                                        level3Sub.setMainCategoryId(add.getId());
+                                        level3Sub.setParentId(level2Sub.getId());
+                                        level3Sub.setName(level3Node.has("name") ? level3Node.get("name").asText() : null);
+                                        level3Sub.setLevel(3L);
+                                        level3Sub.setSortOrder(level3Node.has("sortOrder") ? level3Node.get("sortOrder").asLong() : 0L);
+                                        level3Sub.setStatus(level3Node.has("status") ? level3Node.get("status").asLong() : 1L);
+                                        level3Sub.setSyncCategoryId(level3Id);
+                                        categorySubMapper.insert(level3Sub);
+                                    }
+                                }
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (JsonProcessingException e) {
+            log.error("解析 remark JSON 数据失败", e);
+            throw new RuntimeException("解析分类数据失败", e);
+        }
+
+        bo.setId(add.getId());
+        return true;
+    }
+
+    /**
+     * 修改分类设置主
+     *
+     * @param bo 分类设置主
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhCategoryMainBo bo) {
+        DkhCategoryMain update = MapstructUtils.convert(bo, DkhCategoryMain.class);
+        validEntityBeforeSave(update);
+
+        // 先更新主表数据
+        boolean flag = baseMapper.updateById(update) > 0;
+        if (flag) {
+            // 从数据库获取 syncCategoryId,避免前端不传导致条件不满足
+            DkhCategoryMain dbRecord = baseMapper.selectById(update.getId());
+            Long syncCategoryId = dbRecord != null ? dbRecord.getSyncCategoryId() : bo.getSyncCategoryId();
+
+            if (syncCategoryId != null && StringUtils.isNotBlank(bo.getPanelConfigJson())) {
+                try {
+                    JsonNode rootNode = objectMapper.readTree(bo.getPanelConfigJson());
+                    JsonNode subMenus = rootNode.get("subMenus");
+
+                    if (subMenus != null && subMenus.isArray()) {
+                        // 直接用 panelConfigJson 中的 syncCategoryId 构建分类树,实现远程增量更新
+                        List<CategoryDto> newCategoryTree = buildCategoryTreeFromSubMenus(
+                            bo.getName(),
+                            subMenus,
+                            syncCategoryId
+                        );
+                        remoteCategoryService.updateCategoryTree(syncCategoryId, newCategoryTree);
+                    }
+
+                    // 从远程重新获取完整分类树,获取所有分类的最新ID(含新增分类)
+                    List<CategoryDto> remoteTree = remoteCategoryService.getCategoryTreeById(syncCategoryId);
+                    Map<String, Long> remoteNameToId = buildRemoteNameToIdMap(remoteTree);
+
+                    // 删除旧子菜单,重新保存(带远程 syncCategoryId)
+                    categorySubMapper.delete(Wrappers.<DkhCategorySub>lambdaQuery()
+                        .eq(DkhCategorySub::getMainCategoryId, update.getId()));
+                    saveCategorySubs(update.getId(), bo, remoteNameToId);
+                } catch (Exception e) {
+                    log.error("更新分类树失败", e);
+                    // 分类树更新失败时,仍然更新本地 sub 表(不带远程ID)
+                    categorySubMapper.delete(Wrappers.<DkhCategorySub>lambdaQuery()
+                        .eq(DkhCategorySub::getMainCategoryId, update.getId()));
+                    saveCategorySubs(update.getId(), bo, null);
+                }
+            } else {
+                // 无远程同步时,只更新本地 sub 表
+                categorySubMapper.delete(Wrappers.<DkhCategorySub>lambdaQuery()
+                    .eq(DkhCategorySub::getMainCategoryId, update.getId()));
+                saveCategorySubs(update.getId(), bo, null);
+            }
+        }
+        return flag;
+    }
+
+    /**
+     * 从 subMenus 构建分类树 DTO 列表(树形结构)
+     */
+    private List<CategoryDto> buildCategoryTreeFromSubMenus(String categoryName, JsonNode subMenus, Long rootCategoryId) {
+        List<CategoryDto> result = new ArrayList<>();
+
+        CategoryDto rootDto = new CategoryDto();
+        rootDto.setId(rootCategoryId);
+        rootDto.setCategoryName(categoryName);
+        rootDto.setParentId(0L);
+        rootDto.setClassLevel(1L);
+        rootDto.setDataSource("youyi");
+        rootDto.setPlatform(4L);
+
+        List<CategoryDto> level2Children = new ArrayList<>();
+        if (subMenus != null && subMenus.isArray()) {
+            for (JsonNode level2Node : subMenus) {
+                if (level2Node.has("level") && level2Node.get("level").asInt() == 1) {
+                    JsonNode nestedChildren = level2Node.get("children");
+                    if (nestedChildren != null && nestedChildren.isArray()) {
+                        for (JsonNode nestedChild : nestedChildren) {
+                            level2Children.add(buildCategoryDtoFromNode(nestedChild, rootCategoryId, 2L));
+                        }
+                    }
+                    continue;
+                }
+                level2Children.add(buildCategoryDtoFromNode(level2Node, rootCategoryId, 2L));
+            }
+        }
+
+        rootDto.setChildren(level2Children);
+        result.add(rootDto);
+        return result;
+    }
+
+    /**
+     * 从 JSON 节点构建 CategoryDto(递归),直接从 syncCategoryId 字段获取远程真实ID
+     */
+    private CategoryDto buildCategoryDtoFromNode(JsonNode node, Long parentId, Long classLevel) {
+        CategoryDto dto = new CategoryDto();
+
+        // 从 panelConfigJson 中的 syncCategoryId 字段读取真实远程ID
+        if (node.has("syncCategoryId") && !node.get("syncCategoryId").isNull()) {
+            String syncIdStr = node.get("syncCategoryId").asText();
+            if (StringUtils.isNotBlank(syncIdStr)) {
+                dto.setId(Long.valueOf(syncIdStr));
+            }
+        }
+
+        dto.setCategoryName(node.has("name") ? node.get("name").asText() : null);
+        dto.setParentId(parentId);
+        dto.setClassLevel(classLevel);
+        dto.setIsShow(node.has("status") ? node.get("status").asLong() : 1L);
+        dto.setSort(node.has("sortOrder") ? node.get("sortOrder").asLong() : 0L);
+        dto.setDataSource("youyi");
+        dto.setPlatform(4L);
+
+        JsonNode childrenNode = node.get("children");
+        if (childrenNode != null && childrenNode.isArray() && !childrenNode.isEmpty()) {
+            List<CategoryDto> children = new ArrayList<>();
+            for (JsonNode childNode : childrenNode) {
+                children.add(buildCategoryDtoFromNode(childNode,
+                    dto.getId() != null ? dto.getId() : parentId, classLevel + 1));
+            }
+            dto.setChildren(children);
+        }
+
+        return dto;
+    }
+
+    /**
+     * 保存子菜单数据到本地 dkh_category_sub 表
+     *
+     * @param mainCategoryId 主分类ID
+     * @param bo             分类设置主
+     * @param nameToSyncId   远程分类名称→ID映射(用于回填 syncCategoryId),可为null
+     */
+    private void saveCategorySubs(Long mainCategoryId, DkhCategoryMainBo bo, Map<String, Long> nameToSyncId) {
+        try {
+            if (StringUtils.isNotBlank(bo.getPanelConfigJson())) {
+                JsonNode rootNode = objectMapper.readTree(bo.getPanelConfigJson());
+                JsonNode subMenus = rootNode.get("subMenus");
+
+                if (subMenus != null && subMenus.isArray()) {
+                    for (JsonNode level2Node : subMenus) {
+                        String level2Name = level2Node.has("name") ? level2Node.get("name").asText() : null;
+                        Long level2SyncId = getSyncCategoryIdFromNode(level2Node, 2L, level2Name, nameToSyncId);
+                        DkhCategorySub level2Sub = new DkhCategorySub();
+                        level2Sub.setCustomerId(bo.getCustomerId());
+                        level2Sub.setMainCategoryId(mainCategoryId);
+                        level2Sub.setParentId(0L);
+                        level2Sub.setName(level2Name);
+                        level2Sub.setLevel(2L);
+                        level2Sub.setSortOrder(level2Node.has("sortOrder") ? level2Node.get("sortOrder").asLong() : 0L);
+                        level2Sub.setStatus(level2Node.has("status") ? level2Node.get("status").asLong() : 1L);
+                        level2Sub.setSyncCategoryId(level2SyncId);
+                        categorySubMapper.insert(level2Sub);
+
+                        JsonNode level3Nodes = level2Node.get("children");
+                        if (level3Nodes != null && level3Nodes.isArray() && !level3Nodes.isEmpty()) {
+                            for (JsonNode level3Node : level3Nodes) {
+                                String level3Name = level3Node.has("name") ? level3Node.get("name").asText() : null;
+                                Long level3SyncId = getSyncCategoryIdFromNode(level3Node, 3L, level3Name, nameToSyncId);
+                                DkhCategorySub level3Sub = new DkhCategorySub();
+                                level3Sub.setCustomerId(bo.getCustomerId());
+                                level3Sub.setMainCategoryId(mainCategoryId);
+                                level3Sub.setParentId(level2Sub.getId());
+                                level3Sub.setName(level3Name);
+                                level3Sub.setLevel(3L);
+                                level3Sub.setSortOrder(level3Node.has("sortOrder") ? level3Node.get("sortOrder").asLong() : 0L);
+                                level3Sub.setStatus(level3Node.has("status") ? level3Node.get("status").asLong() : 1L);
+                                level3Sub.setSyncCategoryId(level3SyncId);
+                                categorySubMapper.insert(level3Sub);
+                            }
+                        }
+                    }
+                }
+            }
+        } catch (Exception e) {
+            log.error("保存子菜单数据失败", e);
+        }
+    }
+
+    /**
+     * 从 JSON 节点获取 syncCategoryId:优先从节点字段读取,其次从远程名称映射查找
+     */
+    private Long getSyncCategoryIdFromNode(JsonNode node, Long classLevel, String name, Map<String, Long> nameToSyncId) {
+        // 优先从 JSON 中的 syncCategoryId 字段读取(已存在节点的真实远程ID)
+        if (node.has("syncCategoryId") && !node.get("syncCategoryId").isNull()) {
+            String syncIdStr = node.get("syncCategoryId").asText();
+            if (StringUtils.isNotBlank(syncIdStr)) {
+                return Long.valueOf(syncIdStr);
+            }
+        }
+        // 回退:新增节点从远程名称映射查找
+        if (nameToSyncId != null && StringUtils.isNotBlank(name)) {
+            return nameToSyncId.get(classLevel + ":" + name);
+        }
+        return null;
+    }
+
+    /**
+     * 从远程分类树构建名称→ID映射
+     * key: "classLevel:categoryName" → value: remoteId
+     */
+    private Map<String, Long> buildRemoteNameToIdMap(List<CategoryDto> remoteTree) {
+        Map<String, Long> map = new HashMap<>();
+        if (remoteTree == null) {
+            return map;
+        }
+        for (CategoryDto dto : remoteTree) {
+            if (dto.getId() != null && StringUtils.isNotBlank(dto.getCategoryName())) {
+                map.put(dto.getClassLevel() + ":" + dto.getCategoryName(), dto.getId());
+            }
+        }
+        return map;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhCategoryMain entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 填充解析后的字段(tags、subMenus、panelData)
+     */
+    @SuppressWarnings("unchecked")
+    private void fillParsedFields(DkhCategoryMainVo vo) {
+        try {
+            // 解析 tagsJson → List
+            if (StringUtils.isNotBlank(vo.getTagsJson())) {
+                vo.setTags(objectMapper.readValue(vo.getTagsJson(),
+                    new TypeReference<List<Map<String, Object>>>() {
+                    }));
+            }
+        } catch (Exception e) {
+            log.warn("解析 tagsJson 失败: {}", vo.getTagsJson());
+        }
+        try {
+            // 解析 panelConfigJson → subMenus + panelData
+            if (StringUtils.isNotBlank(vo.getPanelConfigJson())) {
+                Map<String, Object> config = objectMapper.readValue(vo.getPanelConfigJson(),
+                    new TypeReference<Map<String, Object>>() {
+                    });
+
+                // 提取 subMenus
+                if (config.containsKey("subMenus")) {
+                    List<Map<String, Object>> subMenus = (List<Map<String, Object>>) config.get("subMenus");
+                    // 注入 syncCategoryId
+                    injectSyncCategoryId(vo.getId(), subMenus);
+                    vo.setSubMenus(subMenus);
+                    // 回写到 panelConfigJson,使前端也能拿到 syncCategoryId
+                    config.put("subMenus", subMenus);
+                    vo.setPanelConfigJson(objectMapper.writeValueAsString(config));
+                }
+
+                // 构建 panelData(排除 subMenus,保留 mainTitle/subTitle/notes/groups)
+                Map<String, Object> panelData = new java.util.LinkedHashMap<>();
+                if (config.containsKey("mainTitle")) {
+                    panelData.put("mainTitle", config.get("mainTitle"));
+                }
+                if (config.containsKey("subTitle")) {
+                    panelData.put("subTitle", config.get("subTitle"));
+                }
+                if (config.containsKey("notes")) {
+                    panelData.put("notes", config.get("notes"));
+                }
+                if (config.containsKey("groups")) {
+                    panelData.put("groups", config.get("groups"));
+                }
+                vo.setPanelData(panelData);
+            }
+        } catch (Exception e) {
+            log.warn("解析 panelConfigJson 失败: {}", vo.getPanelConfigJson());
+        }
+    }
+
+    /**
+     * 从 dkh_category_sub 表查询 syncCategoryId,注入到 subMenus 树中各节点
+     */
+    @SuppressWarnings("unchecked")
+    private void injectSyncCategoryId(Long mainCategoryId, List<Map<String, Object>> subMenus) {
+        if (mainCategoryId == null || subMenus == null || subMenus.isEmpty()) {
+            return;
+        }
+        // 查询本地子分类记录
+        List<DkhCategorySub> subs = categorySubMapper.selectList(
+            Wrappers.<DkhCategorySub>lambdaQuery()
+                .eq(DkhCategorySub::getMainCategoryId, mainCategoryId));
+        if (subs.isEmpty()) {
+            return;
+        }
+        // 构建 level:name → syncCategoryId 映射
+        Map<String, Long> nameToSyncId = new HashMap<>();
+        for (DkhCategorySub sub : subs) {
+            if (sub.getSyncCategoryId() != null && StringUtils.isNotBlank(sub.getName())) {
+                nameToSyncId.put(sub.getLevel() + ":" + sub.getName(), sub.getSyncCategoryId());
+            }
+        }
+        // 递归注入到 subMenus 树
+        injectSyncCategoryIdRecursive(subMenus, nameToSyncId, 2L);
+    }
+
+    /**
+     * 递归遍历 subMenus 树,注入 syncCategoryId
+     */
+    @SuppressWarnings("unchecked")
+    private void injectSyncCategoryIdRecursive(List<Map<String, Object>> nodes, Map<String, Long> nameToSyncId, Long currentLevel) {
+        if (nodes == null) {
+            return;
+        }
+        for (Map<String, Object> node : nodes) {
+            // 从 nameToSyncId 映射中查找并注入 syncCategoryId
+            String name = (String) node.get("name");
+            if (StringUtils.isNotBlank(name)) {
+                Long syncId = nameToSyncId.get(currentLevel + ":" + name);
+                if (syncId != null) {
+                    node.put("syncCategoryId", String.valueOf(syncId));
+                }
+            }
+            // 递归处理子节点
+            Object children = node.get("children");
+            if (children instanceof List) {
+                List<Map<String, Object>> childNodes = (List<Map<String, Object>>) children;
+                if (!childNodes.isEmpty()) {
+                    injectSyncCategoryIdRecursive(childNodes, nameToSyncId, currentLevel + 1);
+                }
+            }
+        }
+    }
+
+    /**
+     * 修改状态
+     *
+     * @param bo 包含 id 和 status
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateStatus(DkhCategoryMainBo bo) {
+        DkhCategoryMain entity = new DkhCategoryMain();
+        entity.setId(bo.getId());
+        entity.setStatus(bo.getStatus());
+        return baseMapper.updateById(entity) > 0;
+    }
+
+    /**
+     * 校验并批量删除分类设置主信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 140 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhCategorySubServiceImpl.java

@@ -0,0 +1,140 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhCategorySub;
+import org.dromara.mall.domain.bo.DkhCategorySubBo;
+import org.dromara.mall.domain.vo.DkhCategorySubVo;
+import org.dromara.mall.mapper.DkhCategorySubMapper;
+import org.dromara.mall.service.IDkhCategorySubService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 分类设置子菜单Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhCategorySubServiceImpl extends ServiceImpl<DkhCategorySubMapper, DkhCategorySub> implements IDkhCategorySubService {
+
+    private final DkhCategorySubMapper baseMapper;
+
+    /**
+     * 查询分类设置子菜单
+     *
+     * @param id 主键
+     * @return 分类设置子菜单
+     */
+    @Override
+    public DkhCategorySubVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询分类设置子菜单列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 分类设置子菜单分页列表
+     */
+    @Override
+    public TableDataInfo<DkhCategorySubVo> queryPageList(DkhCategorySubBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhCategorySub> lqw = buildQueryWrapper(bo);
+        Page<DkhCategorySubVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的分类设置子菜单列表
+     *
+     * @param bo 查询条件
+     * @return 分类设置子菜单列表
+     */
+    @Override
+    public List<DkhCategorySubVo> queryList(DkhCategorySubBo bo) {
+        LambdaQueryWrapper<DkhCategorySub> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhCategorySub> buildQueryWrapper(DkhCategorySubBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhCategorySub> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhCategorySub::getId);
+        lqw.eq(bo.getCustomerId() != null, DkhCategorySub::getCustomerId, bo.getCustomerId());
+        lqw.eq(bo.getMainCategoryId() != null, DkhCategorySub::getMainCategoryId, bo.getMainCategoryId());
+        lqw.eq(bo.getParentId() != null, DkhCategorySub::getParentId, bo.getParentId());
+        lqw.like(StringUtils.isNotBlank(bo.getName()), DkhCategorySub::getName, bo.getName());
+        lqw.eq(bo.getLevel() != null, DkhCategorySub::getLevel, bo.getLevel());
+        lqw.eq(bo.getSortOrder() != null, DkhCategorySub::getSortOrder, bo.getSortOrder());
+        lqw.eq(bo.getStatus() != null, DkhCategorySub::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhCategorySub::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增分类设置子菜单
+     *
+     * @param bo 分类设置子菜单
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhCategorySubBo bo) {
+        DkhCategorySub add = MapstructUtils.convert(bo, DkhCategorySub.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改分类设置子菜单
+     *
+     * @param bo 分类设置子菜单
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhCategorySubBo bo) {
+        DkhCategorySub update = MapstructUtils.convert(bo, DkhCategorySub.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhCategorySub entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除分类设置子菜单信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 167 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhHeaderMenuServiceImpl.java

@@ -0,0 +1,167 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.ObjectUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhHeaderMenu;
+import org.dromara.mall.domain.bo.DkhHeaderMenuBo;
+import org.dromara.mall.domain.vo.DkhHeaderMenuVo;
+import org.dromara.mall.domain.vo.DkhMallConfigVo;
+import org.dromara.mall.mapper.DkhHeaderMenuMapper;
+import org.dromara.mall.service.IDkhHeaderMenuService;
+import org.dromara.mall.service.IDkhMallConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 顶部导航菜单配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhHeaderMenuServiceImpl extends ServiceImpl<DkhHeaderMenuMapper, DkhHeaderMenu> implements IDkhHeaderMenuService {
+
+    private final DkhHeaderMenuMapper baseMapper;
+
+    private final IDkhMallConfigService dkhMallConfigService;
+
+    /**
+     * 查询顶部导航菜单配置
+     *
+     * @param id 主键
+     * @return 顶部导航菜单配置
+     */
+    @Override
+    public DkhHeaderMenuVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询顶部导航菜单配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 顶部导航菜单配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhHeaderMenuVo> queryPageList(DkhHeaderMenuBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhHeaderMenu> lqw = buildQueryWrapper(bo);
+        Page<DkhHeaderMenuVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        List<DkhHeaderMenuVo> records = result.getRecords();
+        DkhMallConfigVo currentMallConfig =null;
+        if (ObjectUtils.isNotEmpty(bo.getCustomerId())){
+            currentMallConfig= dkhMallConfigService.getCurrentMallConfig(bo.getCustomerId());
+        }
+        for (DkhHeaderMenuVo vo : records) {
+            if (ObjectUtils.isNotEmpty(currentMallConfig)){
+                vo.setHeaderThemeColor(currentMallConfig.getHeaderThemeColor());
+            }
+        }
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的顶部导航菜单配置列表
+     *
+     * @param bo 查询条件
+     * @return 顶部导航菜单配置列表
+     */
+    @Override
+    public List<DkhHeaderMenuVo> queryList(DkhHeaderMenuBo bo) {
+        LambdaQueryWrapper<DkhHeaderMenu> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhHeaderMenu> buildQueryWrapper(DkhHeaderMenuBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhHeaderMenu> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhHeaderMenu::getSortOrder);
+        lqw.eq(bo.getCustomerId() != null, DkhHeaderMenu::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), DkhHeaderMenu::getTitle, bo.getTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getLinkUrl()), DkhHeaderMenu::getLinkUrl, bo.getLinkUrl());
+        lqw.eq(bo.getSortOrder() != null, DkhHeaderMenu::getSortOrder, bo.getSortOrder());
+        lqw.eq(bo.getStatus() != null, DkhHeaderMenu::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhHeaderMenu::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增顶部导航菜单配置
+     *
+     * @param bo 顶部导航菜单配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhHeaderMenuBo bo) {
+        DkhHeaderMenu add = MapstructUtils.convert(bo, DkhHeaderMenu.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改顶部导航菜单配置
+     *
+     * @param bo 顶部导航菜单配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhHeaderMenuBo bo) {
+        DkhHeaderMenu update = MapstructUtils.convert(bo, DkhHeaderMenu.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhHeaderMenu entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除顶部导航菜单配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 状态修改
+     *
+     * @param bo 包含id和status
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateStatus(DkhHeaderMenuBo bo) {
+        DkhHeaderMenu update = new DkhHeaderMenu();
+        update.setId(bo.getId());
+        update.setStatus(bo.getStatus());
+        return baseMapper.updateById(update) > 0;
+    }
+}

+ 156 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhMallConfigServiceImpl.java

@@ -0,0 +1,156 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhMallConfig;
+import org.dromara.mall.domain.bo.DkhMallConfigBo;
+import org.dromara.mall.domain.vo.DkhMallConfigVo;
+import org.dromara.mall.mapper.DkhMallConfigMapper;
+import org.dromara.mall.service.IDkhMallConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 商城首页配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhMallConfigServiceImpl extends ServiceImpl<DkhMallConfigMapper, DkhMallConfig> implements IDkhMallConfigService {
+
+    private final DkhMallConfigMapper baseMapper;
+
+    /**
+     * 查询商城首页配置
+     *
+     * @param id 主键
+     * @return 商城首页配置
+     */
+    @Override
+    public DkhMallConfigVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询商城首页配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 商城首页配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhMallConfigVo> queryPageList(DkhMallConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhMallConfig> lqw = buildQueryWrapper(bo);
+        Page<DkhMallConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的商城首页配置列表
+     *
+     * @param bo 查询条件
+     * @return 商城首页配置列表
+     */
+    @Override
+    public List<DkhMallConfigVo> queryList(DkhMallConfigBo bo) {
+        LambdaQueryWrapper<DkhMallConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhMallConfig> buildQueryWrapper(DkhMallConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhMallConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhMallConfig::getId);
+        lqw.eq(bo.getCustomerId() != null, DkhMallConfig::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getMainTitle()), DkhMallConfig::getMainTitle, bo.getMainTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getLogoUrl()), DkhMallConfig::getLogoUrl, bo.getLogoUrl());
+        lqw.eq(StringUtils.isNotBlank(bo.getSearchPlaceholder()), DkhMallConfig::getSearchPlaceholder, bo.getSearchPlaceholder());
+        lqw.eq(StringUtils.isNotBlank(bo.getHotWords()), DkhMallConfig::getHotWords, bo.getHotWords());
+        lqw.eq(StringUtils.isNotBlank(bo.getBtnText()), DkhMallConfig::getBtnText, bo.getBtnText());
+        lqw.eq(StringUtils.isNotBlank(bo.getThemeColor()), DkhMallConfig::getThemeColor, bo.getThemeColor());
+        lqw.eq(bo.getStatus() != null, DkhMallConfig::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhMallConfig::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增商城首页配置
+     *
+     * @param bo 商城首页配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhMallConfigBo bo) {
+        DkhMallConfig add = MapstructUtils.convert(bo, DkhMallConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改商城首页配置
+     *
+     * @param bo 商城首页配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhMallConfigBo bo) {
+        DkhMallConfig update = MapstructUtils.convert(bo, DkhMallConfig.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhMallConfig entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除商城首页配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 获取当前客户的商城首页配置
+     *
+     * @param customerId 客户ID
+     * @return 商城首页配置,未配置时返回null
+     */
+    @Override
+    public DkhMallConfigVo getCurrentMallConfig(Long customerId) {
+        return baseMapper.selectVoOne(
+            new LambdaQueryWrapper<DkhMallConfig>()
+                .eq(DkhMallConfig::getCustomerId, customerId)
+                .last("LIMIT 1")
+        );
+    }
+}

+ 175 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhRecommendCategoryConfigServiceImpl.java

@@ -0,0 +1,175 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhRecommendCategoryConfig;
+import org.dromara.mall.domain.bo.DkhRecommendCategoryConfigBo;
+import org.dromara.mall.domain.vo.DkhRecommendCategoryConfigVo;
+import org.dromara.mall.mapper.DkhRecommendCategoryConfigMapper;
+import org.dromara.mall.service.IDkhRecommendCategoryConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 推荐分类配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhRecommendCategoryConfigServiceImpl extends ServiceImpl<DkhRecommendCategoryConfigMapper, DkhRecommendCategoryConfig> implements IDkhRecommendCategoryConfigService {
+
+    private final DkhRecommendCategoryConfigMapper baseMapper;
+
+    private static final ObjectMapper objectMapper = new ObjectMapper();
+
+    /**
+     * 查询推荐分类配置
+     *
+     * @param id 主键
+     * @return 推荐分类配置
+     */
+    @Override
+    public DkhRecommendCategoryConfigVo queryById(Long id) {
+        DkhRecommendCategoryConfigVo vo = baseMapper.selectVoById(id);
+        return vo;
+    }
+
+    /**
+     * 分页查询推荐分类配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 推荐分类配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhRecommendCategoryConfigVo> queryPageList(DkhRecommendCategoryConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhRecommendCategoryConfig> lqw = buildQueryWrapper(bo);
+        Page<DkhRecommendCategoryConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的推荐分类配置列表
+     *
+     * @param bo 查询条件
+     * @return 推荐分类配置列表
+     */
+    @Override
+    public List<DkhRecommendCategoryConfigVo> queryList(DkhRecommendCategoryConfigBo bo) {
+        LambdaQueryWrapper<DkhRecommendCategoryConfig> lqw = buildQueryWrapper(bo);
+        List<DkhRecommendCategoryConfigVo> list = baseMapper.selectVoList(lqw);
+        return list;
+    }
+
+    private LambdaQueryWrapper<DkhRecommendCategoryConfig> buildQueryWrapper(DkhRecommendCategoryConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhRecommendCategoryConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhRecommendCategoryConfig::getSortOrder);
+        lqw.eq(bo.getCustomerId() != null, DkhRecommendCategoryConfig::getCustomerId, bo.getCustomerId());
+        lqw.like(StringUtils.isNotBlank(bo.getName()), DkhRecommendCategoryConfig::getName, bo.getName());
+        lqw.eq(StringUtils.isNotBlank(bo.getIconUrl()), DkhRecommendCategoryConfig::getIconUrl, bo.getIconUrl());
+        lqw.eq(StringUtils.isNotBlank(bo.getDataType()), DkhRecommendCategoryConfig::getDataType, bo.getDataType());
+        lqw.eq(StringUtils.isNotBlank(bo.getCategoryPath()), DkhRecommendCategoryConfig::getCategoryPath, bo.getCategoryPath());
+        lqw.eq(StringUtils.isNotBlank(bo.getCategoryLabel()), DkhRecommendCategoryConfig::getCategoryLabel, bo.getCategoryLabel());
+        lqw.eq(StringUtils.isNotBlank(bo.getSelectedProductIds()), DkhRecommendCategoryConfig::getSelectedProductIds, bo.getSelectedProductIds());
+        lqw.eq(bo.getSortOrder() != null, DkhRecommendCategoryConfig::getSortOrder, bo.getSortOrder());
+        lqw.eq(bo.getStatus() != null, DkhRecommendCategoryConfig::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhRecommendCategoryConfig::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增推荐分类配置
+     *
+     * @param bo 推荐分类配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhRecommendCategoryConfigBo bo) {
+        DkhRecommendCategoryConfig add = MapstructUtils.convert(bo, DkhRecommendCategoryConfig.class);
+        // MySQL JSON列不接受空字符串,需转为合法JSON
+        if (StringUtils.isBlank(add.getSelectedProductIds())) {
+            add.setSelectedProductIds("[]");
+        }
+        if (StringUtils.isBlank(add.getCategoryPath())) {
+            add.setCategoryPath("[]");
+        }
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改推荐分类配置
+     *
+     * @param bo 推荐分类配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhRecommendCategoryConfigBo bo) {
+        DkhRecommendCategoryConfig update = MapstructUtils.convert(bo, DkhRecommendCategoryConfig.class);
+        // MySQL JSON列不接受空字符串,需转为合法JSON
+        if (StringUtils.isBlank(update.getSelectedProductIds())) {
+            update.setSelectedProductIds("[]");
+        }
+        if (StringUtils.isBlank(update.getCategoryPath())) {
+            update.setCategoryPath("[]");
+        }
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhRecommendCategoryConfig entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除推荐分类配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    /**
+     * 状态修改
+     *
+     * @param bo 包含id和status
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateStatus(DkhRecommendCategoryConfigBo bo) {
+        DkhRecommendCategoryConfig update = new DkhRecommendCategoryConfig();
+        update.setId(bo.getId());
+        update.setStatus(bo.getStatus());
+        return baseMapper.updateById(update) > 0;
+    }
+}

+ 160 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhRecommendThemeConfigServiceImpl.java

@@ -0,0 +1,160 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhRecommendCategoryConfig;
+import org.dromara.mall.domain.DkhRecommendThemeConfig;
+import org.dromara.mall.domain.EpRecommendCategoryConfig;
+import org.dromara.mall.domain.EpRecommendThemeConfig;
+import org.dromara.mall.domain.bo.DkhCategoryMainBoToDkhCategoryMainMapper;
+import org.dromara.mall.domain.bo.DkhRecommendThemeConfigBo;
+import org.dromara.mall.domain.vo.DkhRecommendCategoryConfigVo;
+import org.dromara.mall.domain.vo.DkhRecommendThemeConfigVo;
+import org.dromara.mall.domain.vo.EpRecommendThemeConfigVo;
+import org.dromara.mall.mapper.DkhRecommendCategoryConfigMapper;
+import org.dromara.mall.mapper.DkhRecommendThemeConfigMapper;
+import org.dromara.mall.service.IDkhRecommendCategoryConfigService;
+import org.dromara.mall.service.IDkhRecommendThemeConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 推荐全局主题配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhRecommendThemeConfigServiceImpl extends ServiceImpl<DkhRecommendThemeConfigMapper, DkhRecommendThemeConfig> implements IDkhRecommendThemeConfigService {
+
+    private final DkhRecommendThemeConfigMapper baseMapper;
+
+private final DkhRecommendCategoryConfigMapper recommendCategoryConfigMapper;
+    /**
+     * 查询推荐全局主题配置
+     *
+     * @param id 主键
+     * @return 推荐全局主题配置
+     */
+    @Override
+    public DkhRecommendThemeConfigVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询推荐全局主题配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 推荐全局主题配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhRecommendThemeConfigVo> queryPageList(DkhRecommendThemeConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhRecommendThemeConfig> lqw = buildQueryWrapper(bo);
+        Page<DkhRecommendThemeConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的推荐全局主题配置列表
+     *
+     * @param bo 查询条件
+     * @return 推荐全局主题配置列表
+     */
+    @Override
+    public List<DkhRecommendThemeConfigVo> queryList(DkhRecommendThemeConfigBo bo) {
+        LambdaQueryWrapper<DkhRecommendThemeConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhRecommendThemeConfig> buildQueryWrapper(DkhRecommendThemeConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhRecommendThemeConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhRecommendThemeConfig::getId);
+        lqw.eq(bo.getCustomerId() != null, DkhRecommendThemeConfig::getCustomerId, bo.getCustomerId());
+        lqw.eq(StringUtils.isNotBlank(bo.getThemeColor()), DkhRecommendThemeConfig::getThemeColor, bo.getThemeColor());
+        lqw.eq(bo.getBgOpacity() != null, DkhRecommendThemeConfig::getBgOpacity, bo.getBgOpacity());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhRecommendThemeConfig::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增推荐全局主题配置
+     *
+     * @param bo 推荐全局主题配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhRecommendThemeConfigBo bo) {
+        DkhRecommendThemeConfig add = MapstructUtils.convert(bo, DkhRecommendThemeConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改推荐全局主题配置
+     *
+     * @param bo 推荐全局主题配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhRecommendThemeConfigBo bo) {
+        DkhRecommendThemeConfig update = MapstructUtils.convert(bo, DkhRecommendThemeConfig.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhRecommendThemeConfig entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除推荐全局主题配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+
+    @Override
+    public DkhRecommendThemeConfigVo getCurrentRecommendThemeConfig(Long customerId) {
+        // 查询是否有配置
+        LambdaQueryWrapper<DkhRecommendThemeConfig> lqw = Wrappers.lambdaQuery();
+        lqw.eq(DkhRecommendThemeConfig::getCustomerId,customerId);
+        lqw.last("LIMIT 1");
+        DkhRecommendThemeConfig config = baseMapper.selectOne(lqw);
+        DkhRecommendThemeConfigVo vo = null;
+        if (null != config) {
+            vo = baseMapper.selectVoById(config.getId());
+            vo.setCategoryConfigList(recommendCategoryConfigMapper.selectVoList(Wrappers.lambdaQuery(DkhRecommendCategoryConfig.class).eq(DkhRecommendCategoryConfig::getCustomerId, customerId).eq(DkhRecommendCategoryConfig::getStatus, 1).orderByAsc(DkhRecommendCategoryConfig::getSortOrder)));
+        }
+        return vo;
+    }
+}

+ 142 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/DkhScenarioConfigServiceImpl.java

@@ -0,0 +1,142 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.mall.domain.DkhScenarioConfig;
+import org.dromara.mall.domain.bo.DkhScenarioConfigBo;
+import org.dromara.mall.domain.vo.DkhScenarioConfigVo;
+import org.dromara.mall.mapper.DkhScenarioConfigMapper;
+import org.dromara.mall.service.IDkhScenarioConfigService;
+import org.springframework.stereotype.Service;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 场景解决方案配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-06-02
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class DkhScenarioConfigServiceImpl extends ServiceImpl<DkhScenarioConfigMapper, DkhScenarioConfig> implements IDkhScenarioConfigService {
+
+    private final DkhScenarioConfigMapper baseMapper;
+
+    /**
+     * 查询场景解决方案配置
+     *
+     * @param id 主键
+     * @return 场景解决方案配置
+     */
+    @Override
+    public DkhScenarioConfigVo queryById(Long id) {
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询场景解决方案配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 场景解决方案配置分页列表
+     */
+    @Override
+    public TableDataInfo<DkhScenarioConfigVo> queryPageList(DkhScenarioConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<DkhScenarioConfig> lqw = buildQueryWrapper(bo);
+        Page<DkhScenarioConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的场景解决方案配置列表
+     *
+     * @param bo 查询条件
+     * @return 场景解决方案配置列表
+     */
+    @Override
+    public List<DkhScenarioConfigVo> queryList(DkhScenarioConfigBo bo) {
+        LambdaQueryWrapper<DkhScenarioConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<DkhScenarioConfig> buildQueryWrapper(DkhScenarioConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<DkhScenarioConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(DkhScenarioConfig::getId);
+        lqw.eq(bo.getCustomerId() != null, DkhScenarioConfig::getCustomerId, bo.getCustomerId());
+        lqw.eq(bo.getStatus() != null, DkhScenarioConfig::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getBgImage()), DkhScenarioConfig::getBgImage, bo.getBgImage());
+        lqw.eq(StringUtils.isNotBlank(bo.getMainTitle()), DkhScenarioConfig::getMainTitle, bo.getMainTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getMainTitleColor()), DkhScenarioConfig::getMainTitleColor, bo.getMainTitleColor());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubTitle()), DkhScenarioConfig::getSubTitle, bo.getSubTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubTitleColor()), DkhScenarioConfig::getSubTitleColor, bo.getSubTitleColor());
+        lqw.eq(StringUtils.isNotBlank(bo.getJumpLink()), DkhScenarioConfig::getJumpLink, bo.getJumpLink());
+        lqw.eq(StringUtils.isNotBlank(bo.getSubCardsJson()), DkhScenarioConfig::getSubCardsJson, bo.getSubCardsJson());
+        lqw.eq(StringUtils.isNotBlank(bo.getPlatformCode()), DkhScenarioConfig::getPlatformCode, bo.getPlatformCode());
+        return lqw;
+    }
+
+    /**
+     * 新增场景解决方案配置
+     *
+     * @param bo 场景解决方案配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(DkhScenarioConfigBo bo) {
+        DkhScenarioConfig add = MapstructUtils.convert(bo, DkhScenarioConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改场景解决方案配置
+     *
+     * @param bo 场景解决方案配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(DkhScenarioConfigBo bo) {
+        DkhScenarioConfig update = MapstructUtils.convert(bo, DkhScenarioConfig.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(DkhScenarioConfig entity) {
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除场景解决方案配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if (isValid) {
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

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

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

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

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

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

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

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

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

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

+ 73 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/pc/PcDkhMenuSettings.java

@@ -0,0 +1,73 @@
+package org.dromara.system.controller.pc;
+
+import lombok.RequiredArgsConstructor;
+import org.dromara.common.core.domain.R;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.satoken.utils.LoginHelper;
+import org.dromara.system.domain.bo.DkhBottomMenuBo;
+import org.dromara.system.domain.bo.DkhTopMenuBo;
+import org.dromara.system.domain.vo.DkhBottomMenuVo;
+import org.dromara.system.domain.vo.DkhCopyrightInfoVo;
+import org.dromara.system.domain.vo.DkhMobileHuicaiConfigVo;
+import org.dromara.system.domain.vo.DkhTopMenuVo;
+import org.dromara.system.service.IDkhBottomMenuService;
+import org.dromara.system.service.IDkhCopyrightInfoService;
+import org.dromara.system.service.IDkhMobileHuicaiConfigService;
+import org.dromara.system.service.IDkhTopMenuService;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+/**
+ * pc大客户菜单设置控制器
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/pcDkhMenuSettings")
+public class PcDkhMenuSettings {
+
+    private final IDkhTopMenuService dkhTopMenuService;
+
+    private final IDkhBottomMenuService dkhBottomMenuService;
+
+    private final IDkhCopyrightInfoService dkhCopyrightInfoService;
+
+    private final IDkhMobileHuicaiConfigService dkhMobileHuicaiConfigService;
+
+    /**
+     * 顶部菜单
+     */
+    @GetMapping("/topMenuList")
+    public TableDataInfo<DkhTopMenuVo> topMenuList(DkhTopMenuBo bo) {
+        bo.setStatus(1L);//启用
+        return dkhTopMenuService.queryTopMenuTreeList(bo);
+    }
+
+    /**
+     * 底部菜单
+     */
+    @GetMapping("/bottomMenuList")
+    public TableDataInfo<DkhBottomMenuVo> bottomMenuList(DkhBottomMenuBo bo) {
+        bo.setStatus(1L);//启用
+        return dkhBottomMenuService.queryBottomMenuTreeList(bo);
+    }
+
+    /**
+     * 获取当前慧采配置信息
+     */
+    @GetMapping("/currentMobileHuicaiConfig")
+    public R<DkhMobileHuicaiConfigVo> getCurrentMobileHuicaiConfig() {
+        return R.ok(dkhMobileHuicaiConfigService.getCurrentMobileHuicaiConfig());
+    }
+
+    /**
+     * 获取当前版权配置信息
+     */
+    @GetMapping("/currentCopyrightInfo")
+    public R<DkhCopyrightInfoVo> getCurrentCopyrightInfo() {
+        return R.ok(dkhCopyrightInfoService.getCurrentCopyrightInfo());
+    }
+}

+ 116 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhBottomMenuController.java

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

+ 114 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhCopyrightInfoController.java

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

+ 115 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhMobileHuicaiConfigController.java

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

+ 115 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/controller/system/DkhTopMenuController.java

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

+ 72 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhBottomMenu.java

@@ -0,0 +1,72 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 大客户底部菜单对象 dkh_bottom_menu
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_bottom_menu")
+public class DkhBottomMenu extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 
+     */
+    private Long parentId;
+
+    /**
+     * 
+     */
+    private String name;
+
+    /**
+     * 
+     */
+    private String link;
+
+    /**
+     * 
+     */
+    private Long sort;
+
+    /**
+     * 
+     */
+    private Long status;
+
+    /**
+     * 
+     */
+    private String target;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 97 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhCopyrightInfo.java

@@ -0,0 +1,97 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 大客户版权信息对象 dkh_copyright_info
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_copyright_info")
+public class DkhCopyrightInfo extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 版权所有
+     */
+    private String owner;
+
+    /**
+     * 备案号
+     */
+    private String icp;
+
+    /**
+     * 公安备案
+     */
+    private String police;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 客服电话
+     */
+    private String customerPhone;
+
+    /**
+     * 客服二维码
+     */
+    private String customerQr;
+
+    /**
+     * 底部Logo
+     */
+    private String logo;
+
+    /**
+     * 公众号名称
+     */
+    private String wechatTitle;
+
+    /**
+     * 公众号二维码
+     */
+    private String wechatQr;
+
+    /**
+     * 微博名称
+     */
+    private String weiboTitle;
+
+    /**
+     * 微博二维码
+     */
+    private String weiboQr;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 77 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhMobileHuicaiConfig.java

@@ -0,0 +1,77 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 大客户手机慧采配置对象 dkh_mobile_huicai_config
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_mobile_huicai_config")
+public class DkhMobileHuicaiConfig extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 
+     */
+    private String menuName;
+
+    /**
+     * 
+     */
+    private String miniProgramTitle;
+
+    /**
+     * 
+     */
+    private String miniProgramSubTitle;
+
+    /**
+     * 
+     */
+    private String miniProgramQr;
+
+    /**
+     * 
+     */
+    private String wechatServiceTitle;
+
+    /**
+     * 
+     */
+    private String wechatServiceSubTitle;
+
+    /**
+     * 
+     */
+    private String wechatServiceQr;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 72 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/DkhTopMenu.java

@@ -0,0 +1,72 @@
+package org.dromara.system.domain;
+
+import org.dromara.common.tenant.core.TenantEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 大客户顶部菜单对象 dkh_top_menu
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("dkh_top_menu")
+public class DkhTopMenu extends TenantEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 
+     */
+    private Long parentId;
+
+    /**
+     * 
+     */
+    private String name;
+
+    /**
+     * 
+     */
+    private String link;
+
+    /**
+     * 
+     */
+    private Long sort;
+
+    /**
+     * 
+     */
+    private Long status;
+
+    /**
+     * 
+     */
+    private String target;
+
+    /**
+     * 删除标志(0代表存在 2代表删除)
+     */
+    @TableLogic
+    private String delFlag;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

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

@@ -47,7 +47,7 @@ public class SysAnnouncement extends TenantEntity {
     /**
      * 封面图片(OSS ID)
      */
-    private Long coverImage;
+    private String coverImage;
 
     /**
      * 是否显示(0否 1是)

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

@@ -0,0 +1,64 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.DkhBottomMenu;
+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.*;
+
+/**
+ * 大客户底部菜单业务对象 dkh_bottom_menu
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhBottomMenu.class, reverseConvertGenerate = false)
+public class DkhBottomMenuBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 
+     */
+    private Long parentId;
+
+    /**
+     * 
+     */
+    private String name;
+
+    /**
+     * 
+     */
+    private String link;
+
+    /**
+     * 
+     */
+    private Long sort;
+
+    /**
+     * 
+     */
+    private Long status;
+
+    /**
+     * 
+     */
+    private String target;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 89 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/DkhCopyrightInfoBo.java

@@ -0,0 +1,89 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.DkhCopyrightInfo;
+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.*;
+
+/**
+ * 大客户版权信息业务对象 dkh_copyright_info
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhCopyrightInfo.class, reverseConvertGenerate = false)
+public class DkhCopyrightInfoBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 版权所有
+     */
+    private String owner;
+
+    /**
+     * 备案号
+     */
+    private String icp;
+
+    /**
+     * 公安备案
+     */
+    private String police;
+
+    /**
+     * 联系电话
+     */
+    private String phone;
+
+    /**
+     * 客服电话
+     */
+    private String customerPhone;
+
+    /**
+     * 客服二维码
+     */
+    private String customerQr;
+
+    /**
+     * 底部Logo
+     */
+    private String logo;
+
+    /**
+     * 公众号名称
+     */
+    private String wechatTitle;
+
+    /**
+     * 公众号二维码
+     */
+    private String wechatQr;
+
+    /**
+     * 微博名称
+     */
+    private String weiboTitle;
+
+    /**
+     * 微博二维码
+     */
+    private String weiboQr;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

+ 69 - 0
ruoyi-modules/ruoyi-system/src/main/java/org/dromara/system/domain/bo/DkhMobileHuicaiConfigBo.java

@@ -0,0 +1,69 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.DkhMobileHuicaiConfig;
+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.*;
+
+/**
+ * 大客户手机慧采配置业务对象 dkh_mobile_huicai_config
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhMobileHuicaiConfig.class, reverseConvertGenerate = false)
+public class DkhMobileHuicaiConfigBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 
+     */
+    private String menuName;
+
+    /**
+     * 
+     */
+    private String miniProgramTitle;
+
+    /**
+     * 
+     */
+    private String miniProgramSubTitle;
+
+    /**
+     * 
+     */
+    private String miniProgramQr;
+
+    /**
+     * 
+     */
+    private String wechatServiceTitle;
+
+    /**
+     * 
+     */
+    private String wechatServiceSubTitle;
+
+    /**
+     * 
+     */
+    private String wechatServiceQr;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

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

@@ -0,0 +1,64 @@
+package org.dromara.system.domain.bo;
+
+import org.dromara.system.domain.DkhTopMenu;
+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.*;
+
+/**
+ * 大客户顶部菜单业务对象 dkh_top_menu
+ *
+ * @author LionLi
+ * @date 2026-06-03
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = DkhTopMenu.class, reverseConvertGenerate = false)
+public class DkhTopMenuBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 
+     */
+    private Long parentId;
+
+    /**
+     * 
+     */
+    private String name;
+
+    /**
+     * 
+     */
+    private String link;
+
+    /**
+     * 
+     */
+    private Long sort;
+
+    /**
+     * 
+     */
+    private Long status;
+
+    /**
+     * 
+     */
+    private String target;
+
+    /**
+     * 备注
+     */
+    private String remark;
+
+
+}

Some files were not shown because too many files changed in this diff