Przeglądaj źródła

feat(mall): 添加商城模块配置文件和表单组件

- 新增账户变更类型配置文件,定义积分、余额、资金、佣金等变动类型
- 添加账户类型配置,包括积分和余额两种类型
- 集成DIY广告位配置,支持首页和优惠券广告位
- 添加系统协议配置,包含服务协议和隐私协议
- 配置管理员应用菜单项,包括商家管理、客户管理、核销等功能
- 定义管理员应用分组,按客户、配送、商家进行分类
- 添加用户端应用配置,提供商家信息和客户管理入口
- 配置底部导航栏,设置首页和个人中心页面链接
- 新增表单组件配置,支持文本输入、日期选择、图片上传等多种组件
- 集成DIY组件库,提供标题、图片广告、图文导航等基础组件
- 添加应用配置文件,设置服务器端口和Nacos注册中心连接参数
肖路 4 miesięcy temu
rodzic
commit
e158524fd8
100 zmienionych plików z 7432 dodań i 8 usunięć
  1. 1 0
      ruoyi-modules/pom.xml
  2. 2 2
      ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/bo.java.vm
  3. 6 6
      ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm
  4. 129 0
      ruoyi-modules/ruoyi-mall/pom.xml
  5. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyAdvController.java
  6. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormController.java
  7. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormFieldsController.java
  8. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormRecordsController.java
  9. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormRecordsFieldsController.java
  10. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormSubmitConfigController.java
  11. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormWriteConfigController.java
  12. 155 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyPageController.java
  13. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyRouteController.java
  14. 106 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyThemeController.java
  15. 68 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyAdv.java
  16. 86 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyForm.java
  17. 91 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormFields.java
  18. 56 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormRecords.java
  19. 101 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormRecordsFields.java
  20. 76 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormSubmitConfig.java
  21. 101 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormWriteConfig.java
  22. 91 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyPage.java
  23. 66 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyRoute.java
  24. 81 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyTheme.java
  25. 66 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyAdvBo.java
  26. 85 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormBo.java
  27. 90 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormFieldsBo.java
  28. 55 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormRecordsBo.java
  29. 99 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormRecordsFieldsBo.java
  30. 77 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormSubmitConfigBo.java
  31. 102 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormWriteConfigBo.java
  32. 90 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyPageBo.java
  33. 64 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyRouteBo.java
  34. 82 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyThemeBo.java
  35. 41 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyAdvParam.java
  36. 41 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyAdvSearchParam.java
  37. 24 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyAdvSortParam.java
  38. 17 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyConfigParam.java
  39. 20 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyLinkParam.java
  40. 23 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyPageInitParam.java
  41. 45 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyPageParam.java
  42. 24 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyPageSearchParam.java
  43. 21 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyRouteSearchParam.java
  44. 34 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyRouteShareParam.java
  45. 18 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeColorParam.java
  46. 29 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeParam.java
  47. 25 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeSetParam.java
  48. 21 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeTitleParam.java
  49. 27 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/SetDiyDataParam.java
  50. 26 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/TemplateParam.java
  51. 87 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyAdvVo.java
  52. 110 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormFieldsVo.java
  53. 122 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormRecordsFieldsVo.java
  54. 68 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormRecordsVo.java
  55. 92 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormSubmitConfigVo.java
  56. 107 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormVo.java
  57. 122 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormWriteConfigVo.java
  58. 122 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyPageVo.java
  59. 88 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyRouteVo.java
  60. 98 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyThemeVo.java
  61. 17 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/SceneDomainVo.java
  62. 29 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/StartUpPageConfigVo.java
  63. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyAdvMapper.java
  64. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyFormFieldsMapper.java
  65. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyFormMapper.java
  66. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyFormRecordsFieldsMapper.java
  67. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyFormRecordsMapper.java
  68. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyFormSubmitConfigMapper.java
  69. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyFormWriteConfigMapper.java
  70. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyPageMapper.java
  71. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyRouteMapper.java
  72. 15 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/mapper/NsDiyThemeMapper.java
  73. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyAdvService.java
  74. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyFormFieldsService.java
  75. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyFormRecordsFieldsService.java
  76. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyFormRecordsService.java
  77. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyFormService.java
  78. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyFormSubmitConfigService.java
  79. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyFormWriteConfigService.java
  80. 112 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyPageService.java
  81. 79 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyRouteService.java
  82. 70 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyThemeService.java
  83. 139 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyAdvServiceImpl.java
  84. 144 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormFieldsServiceImpl.java
  85. 146 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormRecordsFieldsServiceImpl.java
  86. 137 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormRecordsServiceImpl.java
  87. 142 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormServiceImpl.java
  88. 141 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormSubmitConfigServiceImpl.java
  89. 146 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormWriteConfigServiceImpl.java
  90. 509 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyPageServiceImpl.java
  91. 255 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyRouteServiceImpl.java
  92. 142 0
      ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyThemeServiceImpl.java
  93. 34 0
      ruoyi-modules/ruoyi-mall/src/main/resources/application.yml
  94. 101 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/account_change_type.json
  95. 10 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/account_type.json
  96. 47 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/app.json
  97. 17 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/app_group.json
  98. 20 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/app_user.json
  99. 26 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/bottom_nav.json
  100. 3 0
      ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/stat.json

+ 1 - 0
ruoyi-modules/pom.xml

@@ -18,6 +18,7 @@
 	    <module>ruoyi-product</module>
         <module>ruoyi-customer</module>
 	    <module>ruoyi-external</module>
+	    <module>ruoyi-mall</module>
     </modules>
 
     <artifactId>ruoyi-modules</artifactId>

+ 2 - 2
ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/bo.java.vm

@@ -37,9 +37,9 @@ public class ${ClassName}Bo extends BaseEntity {
 #end
 #if($column.required)
 #if($column.javaType == 'String')
-    @NotBlank(message = "$column.columnComment不能为空", groups = { $Group })
+    //@NotBlank(message = "$column.columnComment不能为空", groups = { $Group })
 #else
-    @NotNull(message = "$column.columnComment不能为空", groups = { $Group })
+    //@NotNull(message = "$column.columnComment不能为空", groups = { $Group })
 #end
 #end
     private $column.javaType $column.javaField;

+ 6 - 6
ruoyi-modules/ruoyi-gen/src/main/resources/vm/java/controller.java.vm

@@ -43,7 +43,7 @@ public class ${ClassName}Controller extends BaseController {
     /**
      * 查询${functionName}列表
      */
-    @SaCheckPermission("${permissionPrefix}:list")
+    //@SaCheckPermission("${permissionPrefix}:list")
     @GetMapping("/list")
 #if($table.crud)
     public TableDataInfo<${ClassName}Vo> list(${ClassName}Bo bo, PageQuery pageQuery) {
@@ -59,7 +59,7 @@ public class ${ClassName}Controller extends BaseController {
     /**
      * 导出${functionName}列表
      */
-    @SaCheckPermission("${permissionPrefix}:export")
+    //@SaCheckPermission("${permissionPrefix}:export")
     @Log(title = "${functionName}", businessType = BusinessType.EXPORT)
     @PostMapping("/export")
     public void export(${ClassName}Bo bo, HttpServletResponse response) {
@@ -72,7 +72,7 @@ public class ${ClassName}Controller extends BaseController {
      *
      * @param ${pkColumn.javaField} 主键
      */
-    @SaCheckPermission("${permissionPrefix}:query")
+    //@SaCheckPermission("${permissionPrefix}:query")
     @GetMapping("/{${pkColumn.javaField}}")
     public R<${ClassName}Vo> getInfo(@NotNull(message = "主键不能为空")
                                      @PathVariable("${pkColumn.javaField}") ${pkColumn.javaType} ${pkColumn.javaField}) {
@@ -82,7 +82,7 @@ public class ${ClassName}Controller extends BaseController {
     /**
      * 新增${functionName}
      */
-    @SaCheckPermission("${permissionPrefix}:add")
+    //@SaCheckPermission("${permissionPrefix}:add")
     @Log(title = "${functionName}", businessType = BusinessType.INSERT)
     @RepeatSubmit()
     @PostMapping()
@@ -93,7 +93,7 @@ public class ${ClassName}Controller extends BaseController {
     /**
      * 修改${functionName}
      */
-    @SaCheckPermission("${permissionPrefix}:edit")
+    //@SaCheckPermission("${permissionPrefix}:edit")
     @Log(title = "${functionName}", businessType = BusinessType.UPDATE)
     @RepeatSubmit()
     @PutMapping()
@@ -106,7 +106,7 @@ public class ${ClassName}Controller extends BaseController {
      *
      * @param ${pkColumn.javaField}s 主键串
      */
-    @SaCheckPermission("${permissionPrefix}:remove")
+    //@SaCheckPermission("${permissionPrefix}:remove")
     @Log(title = "${functionName}", businessType = BusinessType.DELETE)
     @DeleteMapping("/{${pkColumn.javaField}s}")
     public R<Void> remove(@NotEmpty(message = "主键不能为空")

+ 129 - 0
ruoyi-modules/ruoyi-mall/pom.xml

@@ -0,0 +1,129 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+    <parent>
+        <groupId>org.dromara</groupId>
+        <artifactId>ruoyi-modules</artifactId>
+        <version>${revision}</version>
+    </parent>
+    <modelVersion>4.0.0</modelVersion>
+
+
+    <artifactId>ruoyi-mall</artifactId>
+    <dependencies>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-nacos</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-sentinel</artifactId>
+        </dependency>
+
+        <!-- RuoYi Common Log -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-log</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-service-impl</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-doc</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-web</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-mybatis</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-dubbo</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-seata</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-idempotent</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-tenant</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-security</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-translation</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-sensitive</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-common-encrypt</artifactId>
+        </dependency>
+
+        <!-- RuoYi Api System -->
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-system</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-customer</artifactId>
+        </dependency>
+
+        <dependency>
+            <groupId>org.dromara</groupId>
+            <artifactId>ruoyi-api-resource</artifactId>
+        </dependency>
+
+
+    </dependencies>
+
+    <build>
+        <finalName>${project.artifactId}</finalName>
+        <plugins>
+            <plugin>
+                <groupId>org.springframework.boot</groupId>
+                <artifactId>spring-boot-maven-plugin</artifactId>
+                <version>${spring-boot.version}</version>
+                <executions>
+                    <execution>
+                        <goals>
+                            <goal>repackage</goal>
+                        </goals>
+                    </execution>
+                </executions>
+            </plugin>
+        </plugins>
+    </build>
+
+</project>

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

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormController.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.NsDiyFormVo;
+import org.dromara.mall.domain.bo.NsDiyFormBo;
+import org.dromara.mall.service.INsDiyFormService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 万能单
+ * 前端访问路由地址为:/mall/diyForm
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/diyForm")
+public class NsDiyFormController extends BaseController {
+
+    private final INsDiyFormService nsDiyFormService;
+
+    /**
+     * 查询万能单列表
+     */
+    //@SaCheckPermission("mall:diyForm:list")
+    @GetMapping("/list")
+    public TableDataInfo<NsDiyFormVo> list(NsDiyFormBo bo, PageQuery pageQuery) {
+        return nsDiyFormService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出万能单列表
+     */
+    //@SaCheckPermission("mall:diyForm:export")
+    @Log(title = "万能单", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(NsDiyFormBo bo, HttpServletResponse response) {
+        List<NsDiyFormVo> list = nsDiyFormService.queryList(bo);
+        ExcelUtil.exportExcel(list, "万能单", NsDiyFormVo.class, response);
+    }
+
+    /**
+     * 获取万能单详细信息
+     *
+     * @param formId 主键
+     */
+    //@SaCheckPermission("mall:diyForm:query")
+    @GetMapping("/{formId}")
+    public R<NsDiyFormVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("formId") Long formId) {
+        return R.ok(nsDiyFormService.queryById(formId));
+    }
+
+    /**
+     * 新增万能单
+     */
+    //@SaCheckPermission("mall:diyForm:add")
+    @Log(title = "万能单", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody NsDiyFormBo bo) {
+        return toAjax(nsDiyFormService.insertByBo(bo));
+    }
+
+    /**
+     * 修改万能单
+     */
+    //@SaCheckPermission("mall:diyForm:edit")
+    @Log(title = "万能单", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody NsDiyFormBo bo) {
+        return toAjax(nsDiyFormService.updateByBo(bo));
+    }
+
+    /**
+     * 删除万能单
+     *
+     * @param formIds 主键串
+     */
+    //@SaCheckPermission("mall:diyForm:remove")
+    @Log(title = "万能单", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{formIds}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("formIds") Long[] formIds) {
+        return toAjax(nsDiyFormService.deleteWithValidByIds(List.of(formIds), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormFieldsController.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.NsDiyFormFieldsVo;
+import org.dromara.mall.domain.bo.NsDiyFormFieldsBo;
+import org.dromara.mall.service.INsDiyFormFieldsService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 万能单字段
+ * 前端访问路由地址为:/mall/diyFormFields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/diyFormFields")
+public class NsDiyFormFieldsController extends BaseController {
+
+    private final INsDiyFormFieldsService nsDiyFormFieldsService;
+
+    /**
+     * 查询万能单字段列表
+     */
+    //@SaCheckPermission("mall:diyFormFields:list")
+    @GetMapping("/list")
+    public TableDataInfo<NsDiyFormFieldsVo> list(NsDiyFormFieldsBo bo, PageQuery pageQuery) {
+        return nsDiyFormFieldsService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出万能单字段列表
+     */
+    //@SaCheckPermission("mall:diyFormFields:export")
+    @Log(title = "万能单字段", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(NsDiyFormFieldsBo bo, HttpServletResponse response) {
+        List<NsDiyFormFieldsVo> list = nsDiyFormFieldsService.queryList(bo);
+        ExcelUtil.exportExcel(list, "万能单字段", NsDiyFormFieldsVo.class, response);
+    }
+
+    /**
+     * 获取万能单字段详细信息
+     *
+     * @param fieldId 主键
+     */
+    //@SaCheckPermission("mall:diyFormFields:query")
+    @GetMapping("/{fieldId}")
+    public R<NsDiyFormFieldsVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("fieldId") Long fieldId) {
+        return R.ok(nsDiyFormFieldsService.queryById(fieldId));
+    }
+
+    /**
+     * 新增万能单字段
+     */
+    //@SaCheckPermission("mall:diyFormFields:add")
+    @Log(title = "万能单字段", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody NsDiyFormFieldsBo bo) {
+        return toAjax(nsDiyFormFieldsService.insertByBo(bo));
+    }
+
+    /**
+     * 修改万能单字段
+     */
+    //@SaCheckPermission("mall:diyFormFields:edit")
+    @Log(title = "万能单字段", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody NsDiyFormFieldsBo bo) {
+        return toAjax(nsDiyFormFieldsService.updateByBo(bo));
+    }
+
+    /**
+     * 删除万能单字段
+     *
+     * @param fieldIds 主键串
+     */
+    //@SaCheckPermission("mall:diyFormFields:remove")
+    @Log(title = "万能单字段", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{fieldIds}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("fieldIds") Long[] fieldIds) {
+        return toAjax(nsDiyFormFieldsService.deleteWithValidByIds(List.of(fieldIds), true));
+    }
+}

+ 106 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyFormRecordsController.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.NsDiyFormRecordsVo;
+import org.dromara.mall.domain.bo.NsDiyFormRecordsBo;
+import org.dromara.mall.service.INsDiyFormRecordsService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 万能单填写记录
+ * 前端访问路由地址为:/mall/diyFormRecords
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/diyFormRecords")
+public class NsDiyFormRecordsController extends BaseController {
+
+    private final INsDiyFormRecordsService nsDiyFormRecordsService;
+
+    /**
+     * 查询万能单填写记录列表
+     */
+    //@SaCheckPermission("mall:diyFormRecords:list")
+    @GetMapping("/list")
+    public TableDataInfo<NsDiyFormRecordsVo> list(NsDiyFormRecordsBo bo, PageQuery pageQuery) {
+        return nsDiyFormRecordsService.queryPageList(bo, pageQuery);
+    }
+
+    /**
+     * 导出万能单填写记录列表
+     */
+    //@SaCheckPermission("mall:diyFormRecords:export")
+    @Log(title = "万能单填写记录", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(NsDiyFormRecordsBo bo, HttpServletResponse response) {
+        List<NsDiyFormRecordsVo> list = nsDiyFormRecordsService.queryList(bo);
+        ExcelUtil.exportExcel(list, "万能单填写记录", NsDiyFormRecordsVo.class, response);
+    }
+
+    /**
+     * 获取万能单填写记录详细信息
+     *
+     * @param recordId 主键
+     */
+    //@SaCheckPermission("mall:diyFormRecords:query")
+    @GetMapping("/{recordId}")
+    public R<NsDiyFormRecordsVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("recordId") Long recordId) {
+        return R.ok(nsDiyFormRecordsService.queryById(recordId));
+    }
+
+    /**
+     * 新增万能单填写记录
+     */
+    //@SaCheckPermission("mall:diyFormRecords:add")
+    @Log(title = "万能单填写记录", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody NsDiyFormRecordsBo bo) {
+        return toAjax(nsDiyFormRecordsService.insertByBo(bo));
+    }
+
+    /**
+     * 修改万能单填写记录
+     */
+    //@SaCheckPermission("mall:diyFormRecords:edit")
+    @Log(title = "万能单填写记录", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody NsDiyFormRecordsBo bo) {
+        return toAjax(nsDiyFormRecordsService.updateByBo(bo));
+    }
+
+    /**
+     * 删除万能单填写记录
+     *
+     * @param recordIds 主键串
+     */
+    //@SaCheckPermission("mall:diyFormRecords:remove")
+    @Log(title = "万能单填写记录", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{recordIds}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("recordIds") Long[] recordIds) {
+        return toAjax(nsDiyFormRecordsService.deleteWithValidByIds(List.of(recordIds), true));
+    }
+}

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

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

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

+ 155 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/controller/NsDiyPageController.java

@@ -0,0 +1,155 @@
+package org.dromara.mall.controller;
+
+import java.util.List;
+
+import cn.hutool.json.JSONObject;
+import lombok.RequiredArgsConstructor;
+import jakarta.servlet.http.HttpServletResponse;
+import jakarta.validation.constraints.*;
+import cn.dev33.satoken.annotation.SaCheckPermission;
+import org.dromara.mall.domain.param.DiyPageInitParam;
+import org.dromara.mall.domain.param.DiyPageSearchParam;
+import org.dromara.mall.domain.param.TemplateParam;
+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.NsDiyPageVo;
+import org.dromara.mall.domain.bo.NsDiyPageBo;
+import org.dromara.mall.service.INsDiyPageService;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+
+/**
+ * 自定义页面
+ * 前端访问路由地址为:/mall/diyPage
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Validated
+@RequiredArgsConstructor
+@RestController
+@RequestMapping("/diyPage")
+public class NsDiyPageController extends BaseController {
+
+    private final INsDiyPageService nsDiyPageService;
+
+//    /**
+//     * 查询自定义页面列表
+//     */
+//    //@SaCheckPermission("mall:diyPage:list")
+//    @GetMapping("/list")
+//    public TableDataInfo<NsDiyPageVo> list(NsDiyPageBo bo, PageQuery pageQuery) {
+//        return nsDiyPageService.queryPageList(bo, pageQuery);
+//    }
+
+    /**
+     * 导出自定义页面列表
+     */
+    //@SaCheckPermission("mall:diyPage:export")
+    @Log(title = "自定义页面", businessType = BusinessType.EXPORT)
+    @PostMapping("/export")
+    public void export(NsDiyPageBo bo, HttpServletResponse response) {
+        List<NsDiyPageVo> list = nsDiyPageService.queryList(bo);
+        ExcelUtil.exportExcel(list, "自定义页面", NsDiyPageVo.class, response);
+    }
+
+    /**
+     * 获取自定义页面详细信息
+     *
+     * @param id 主键
+     */
+    //@SaCheckPermission("mall:diyPage:query")
+    @GetMapping("/{id}")
+    public R<NsDiyPageVo> getInfo(@NotNull(message = "主键不能为空")
+                                     @PathVariable("id") Long id) {
+        return R.ok(nsDiyPageService.queryById(id));
+    }
+
+    /**
+     * 新增自定义页面
+     */
+    //@SaCheckPermission("mall:diyPage:add")
+    @Log(title = "自定义页面", businessType = BusinessType.INSERT)
+    @RepeatSubmit()
+    @PostMapping()
+    public R<Void> add(@Validated(AddGroup.class) @RequestBody NsDiyPageBo bo) {
+        return toAjax(nsDiyPageService.insertByBo(bo));
+    }
+
+    /**
+     * 修改自定义页面
+     */
+    //@SaCheckPermission("mall:diyPage:edit")
+    @Log(title = "自定义页面", businessType = BusinessType.UPDATE)
+    @RepeatSubmit()
+    @PutMapping()
+    public R<Void> edit(@Validated(EditGroup.class) @RequestBody NsDiyPageBo bo) {
+        return toAjax(nsDiyPageService.updateByBo(bo));
+    }
+
+    /**
+     * 删除自定义页面
+     *
+     * @param ids 主键串
+     */
+    //@SaCheckPermission("mall:diyPage:remove")
+    @Log(title = "自定义页面", businessType = BusinessType.DELETE)
+    @DeleteMapping("/{ids}")
+    public R<Void> remove(@NotEmpty(message = "主键不能为空")
+                          @PathVariable("ids") Long[] ids) {
+        return toAjax(nsDiyPageService.deleteWithValidByIds(List.of(ids), true));
+    }
+
+    /**
+     * 自定义页面模版
+     *
+     * @param param
+     * @return
+     */
+    @GetMapping("/template")
+    public R<JSONObject> getTemplate(TemplateParam param) {
+        return R.ok(nsDiyPageService.getTemplate(param));
+    }
+
+    /**
+     * 自定义页面分页列表
+     *
+     * @param pageQuery 分页参数
+     * @param searchParam 搜索参数
+     * @return Result<Object>
+     */
+    @GetMapping("/diy")
+    public TableDataInfo<NsDiyPageVo> getDiyPage(DiyPageSearchParam searchParam, PageQuery pageQuery) {
+        TableDataInfo<NsDiyPageVo> tableDataInfo = nsDiyPageService.getDiyPage(searchParam, pageQuery);
+        return tableDataInfo;
+    }
+
+
+    /**
+     * 获取页面装修列表
+     * @param searchParam
+     * @return
+     */
+    @GetMapping("/decorate")
+    public R<JSONObject> getDecoratePage(DiyPageSearchParam searchParam) {
+        return R.ok(nsDiyPageService.getDecoratePage(searchParam));
+    }
+
+    /**
+     * 页面初始化数据
+     * @param
+     * @return
+     */
+    @GetMapping("/init")
+    public R<NsDiyPageVo> getPageInit(@Validated DiyPageInitParam param) {
+        return R.ok(nsDiyPageService.getPageInit(param));
+    }
+}

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

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

+ 68 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyAdv.java

@@ -0,0 +1,68 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+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;
+
+/**
+ * 广告对象 ns_diy_adv
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_adv")
+public class NsDiyAdv extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @TableId(value = "adv_id")
+    private Long advId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 广告位key
+     */
+    private String apKey;
+
+    /**
+     * 广告内容描述
+     */
+    private String advTitle;
+
+    /**
+     * 广告链接
+     */
+    private String advUrl;
+
+    /**
+     * 广告内容图片
+     */
+    private String advImage;
+
+    /**
+     * 排序号
+     */
+    private Long slideSort;
+
+    /**
+     * 背景色
+     */
+    private String background;
+
+
+}

+ 86 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyForm.java

@@ -0,0 +1,86 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 万能单对象 ns_diy_form
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_form")
+public class NsDiyForm extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表单id
+     */
+    @TableId(value = "form_id")
+    private Long formId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 表单名称(用于后台展示)
+     */
+    private String pageTitle;
+
+    /**
+     * 表单名称(用于前台展示)
+     */
+    private String title;
+
+    /**
+     * 表单类型
+     */
+    private String type;
+
+    /**
+     * 状态(0,关闭,1:开启)
+     */
+    private Long status;
+
+    /**
+     * 模板名称
+     */
+    private String template;
+
+    /**
+     * 表单数据,json格式,包含展示组件
+     */
+    private String value;
+
+    /**
+     * 所属插件标识
+     */
+    private String addon;
+
+    /**
+     * 分享内容
+     */
+    private String share;
+
+    /**
+     * 表单填写总数量
+     */
+    private Long writeNum;
+
+    /**
+     * 备注说明
+     */
+    private String remark;
+
+
+}

+ 91 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormFields.java

@@ -0,0 +1,91 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 万能单字段对象 ns_diy_form_fields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_form_fields")
+public class NsDiyFormFields extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 字段id
+     */
+    @TableId(value = "field_id")
+    private Long fieldId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 字段唯一标识
+     */
+    private String fieldKey;
+
+    /**
+     * 字段类型
+     */
+    private String fieldType;
+
+    /**
+     * 字段名称
+     */
+    private String fieldName;
+
+    /**
+     * 字段说明
+     */
+    private String fieldRemark;
+
+    /**
+     * 字段默认值
+     */
+    private String fieldDefault;
+
+    /**
+     * 字段填写总数量
+     */
+    private Long writeNum;
+
+    /**
+     * 字段是否必填 0:否 1:是
+     */
+    private Long fieldRequired;
+
+    /**
+     * 字段是否隐藏 0:否 1:是
+     */
+    private Long fieldHidden;
+
+    /**
+     * 字段内容防重复 0:否 1:是
+     */
+    private Long fieldUnique;
+
+    /**
+     * 隐私保护 0:关闭 1:开启
+     */
+    private Long privacyProtection;
+
+
+}

+ 56 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormRecords.java

@@ -0,0 +1,56 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 万能单填写记录对象 ns_diy_form_records
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_form_records")
+public class NsDiyFormRecords extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表单填写记录id
+     */
+    @TableId(value = "record_id")
+    private Long recordId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 填写的表单数据
+     */
+    private String value;
+
+    /**
+     * 填写人会员id
+     */
+    private Long memberId;
+
+    /**
+     * 关联业务id
+     */
+    private Long relateId;
+
+
+}

+ 101 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormRecordsFields.java

@@ -0,0 +1,101 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 万能单填写字段对象 ns_diy_form_records_fields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_form_records_fields")
+public class NsDiyFormRecordsFields extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 关联表单字段id
+     */
+    private Long formFieldId;
+
+    /**
+     * 关联表单填写记录id
+     */
+    private Long recordId;
+
+    /**
+     * 填写会员id
+     */
+    private Long memberId;
+
+    /**
+     * 字段唯一标识
+     */
+    private String fieldKey;
+
+    /**
+     * 字段类型
+     */
+    private String fieldType;
+
+    /**
+     * 字段名称
+     */
+    private String fieldName;
+
+    /**
+     * 字段值,根据类型展示对应效果
+     */
+    private String fieldValue;
+
+    /**
+     * 字段是否必填 0:否 1:是
+     */
+    private Long fieldRequired;
+
+    /**
+     * 字段是否隐藏 0:否 1:是
+     */
+    private Long fieldHidden;
+
+    /**
+     * 字段内容防重复 0:否 1:是
+     */
+    private Long fieldUnique;
+
+    /**
+     * 隐私保护 0:关闭 1:开启
+     */
+    private Long privacyProtection;
+
+    /**
+     * 字段修改次数
+     */
+    private Long updateNum;
+
+
+}

+ 76 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormSubmitConfig.java

@@ -0,0 +1,76 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 万能单提交页配置对象 ns_diy_form_submit_config
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_form_submit_config")
+public class NsDiyFormSubmitConfig extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 填表人提交后操作,text:文字信息,voucher:核销凭证
+     */
+    private String submitAfterAction;
+
+    /**
+     * 提示内容类型,default:默认提示,diy:自定义提示
+     */
+    private String tipsType;
+
+    /**
+     * 自定义提示内容
+     */
+    private String tipsText;
+
+    /**
+     * 核销凭证有效期限制类型,no_limit:不限制,specify_time:指定固定开始结束时间,submission_time:按提交时间设置有效期
+     */
+    private String timeLimitType;
+
+    /**
+     * 核销凭证时间限制规则,json格式
+     */
+    private String timeLimitRule;
+
+    /**
+     * 核销凭证内容,json格式
+     */
+    private String voucherContentRule;
+
+    /**
+     * 填写成功后续操作
+     */
+    private String successAfterAction;
+
+
+}

+ 101 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyFormWriteConfig.java

@@ -0,0 +1,101 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 万能单填写配置对象 ns_diy_form_write_config
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_form_write_config")
+public class NsDiyFormWriteConfig extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 填写方式,no_limit:不限制,scan:仅限微信扫一扫,url:仅限链接进入
+     */
+    private String writeWay;
+
+    /**
+     * 参与会员,all_member:所有会员参与,selected_member_level:指定会员等级,selected_member_label:指定会员标签
+     */
+    private String joinMemberType;
+
+    /**
+     * 会员等级id集合
+     */
+    private String levelIds;
+
+    /**
+     * 会员标签id集合
+     */
+    private String labelIds;
+
+    /**
+     * 每人可填写次数,no_limit:不限制,diy:自定义
+     */
+    private String memberWriteType;
+
+    /**
+     * 每人可填写次数自定义规则
+     */
+    private String memberWriteRule;
+
+    /**
+     * 表单可填写数量,no_limit:不限制,diy:自定义
+     */
+    private String formWriteType;
+
+    /**
+     * 表单可填写总数自定义规则
+     */
+    private String formWriteRule;
+
+    /**
+     * 填写时间限制类型,no_limit:不限制, specify_time:指定开始结束时间,open_day_time:设置每日开启时间
+     */
+    private String timeLimitType;
+
+    /**
+     * 填写时间限制规则
+     */
+    private String timeLimitRule;
+
+    /**
+     * 是否允许修改自己填写的内容,0:否,1:是
+     */
+    private Long isAllowUpdateContent;
+
+    /**
+     * 表单填写须知
+     */
+    private String writeInstruction;
+
+
+}

+ 91 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyPage.java

@@ -0,0 +1,91 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 自定义页面对象 ns_diy_page
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_page")
+public class NsDiyPage extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 页面名称(用于后台展示)
+     */
+    private String pageTitle;
+
+    /**
+     * 页面标题(用于前台展示)
+     */
+    private String title;
+
+    /**
+     * 页面标识
+     */
+    private String name;
+
+    /**
+     * 页面模板
+     */
+    private String type;
+
+    /**
+     * 模板名称
+     */
+    private String template;
+
+    /**
+     * 页面展示模式,diy:自定义,fixed:固定
+     */
+    private String mode;
+
+    /**
+     * 页面数据,json格式
+     */
+    private String value;
+
+    /**
+     * 是否默认页面,1:是,0:否
+     */
+    private Long isDefault;
+
+    /**
+     * 数据是否发生过变化,1:变化了,2:没有
+     */
+    private Long isChange;
+
+    /**
+     * 分享内容
+     */
+    private String share;
+
+    /**
+     * 访问量
+     */
+    private Long visitCount;
+
+
+}

+ 66 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/NsDiyRoute.java

@@ -0,0 +1,66 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 自定义路由对象 ns_diy_route
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_route")
+public class NsDiyRoute extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 页面名称
+     */
+    private String title;
+
+    /**
+     * 页面标识
+     */
+    private String name;
+
+    /**
+     * 页面路径
+     */
+    private String page;
+
+    /**
+     * 分享内容
+     */
+    private String share;
+
+    /**
+     * 是否支持分享
+     */
+    private Long isShare;
+
+    /**
+     * 排序
+     */
+    private Long sort;
+
+
+}

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

@@ -0,0 +1,81 @@
+package org.dromara.mall.domain;
+
+import org.dromara.common.mybatis.core.domain.BaseEntity;
+import com.baomidou.mybatisplus.annotation.*;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+import java.io.Serial;
+
+/**
+ * 自定义主题配色对象 ns_diy_theme
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("ns_diy_theme")
+public class NsDiyTheme extends BaseEntity {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @TableId(value = "id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 颜色名称
+     */
+    private String title;
+
+    /**
+     * 插件类型app,addon
+     */
+    private String type;
+
+    /**
+     * 所属应用,app:系统,shop:商城、o2o:上门服务
+     */
+    private String addon;
+
+    /**
+     * 模式,default:默认【跟随系统】,diy:自定义配色
+     */
+    private String mode;
+
+    /**
+     * 配色类型,default:默认,diy:自定义
+     */
+    private String themeType;
+
+    /**
+     * 当前色调的默认值
+     */
+    private String defaultTheme;
+
+    /**
+     * 当前色调
+     */
+    private String theme;
+
+    /**
+     * 新增颜色集合
+     */
+    private String newTheme;
+
+    /**
+     * 已选色调,0:否,1.是
+     */
+    private Long isSelected;
+
+
+}

+ 66 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyAdvBo.java

@@ -0,0 +1,66 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyAdv;
+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;
+
+/**
+ * 广告业务对象 ns_diy_adv
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyAdv.class, reverseConvertGenerate = false)
+public class NsDiyAdvBo extends BaseEntity {
+
+    /**
+     * 主键
+     */
+    private Long advId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 广告位key
+     */
+    private String apKey;
+
+    /**
+     * 广告内容描述
+     */
+    private String advTitle;
+
+    /**
+     * 广告链接
+     */
+    private String advUrl;
+
+    /**
+     * 广告内容图片
+     */
+    private String advImage;
+
+    /**
+     * 排序号
+     */
+    private Long slideSort;
+
+    /**
+     * 背景色
+     */
+    private String background;
+
+
+}

+ 85 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormBo.java

@@ -0,0 +1,85 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyForm;
+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.*;
+
+/**
+ * 万能单业务对象 ns_diy_form
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyForm.class, reverseConvertGenerate = false)
+public class NsDiyFormBo extends BaseEntity {
+
+    /**
+     * 表单id
+     */
+    private Long formId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 表单名称(用于后台展示)
+     */
+    private String pageTitle;
+
+    /**
+     * 表单名称(用于前台展示)
+     */
+    private String title;
+
+    /**
+     * 表单类型
+     */
+    private String type;
+
+    /**
+     * 状态(0,关闭,1:开启)
+     */
+    private Long status;
+
+    /**
+     * 模板名称
+     */
+    private String template;
+
+    /**
+     * 表单数据,json格式,包含展示组件
+     */
+    //@NotBlank(message = "表单数据,json格式,包含展示组件不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String value;
+
+    /**
+     * 所属插件标识
+     */
+    private String addon;
+
+    /**
+     * 分享内容
+     */
+    private String share;
+
+    /**
+     * 表单填写总数量
+     */
+    private Long writeNum;
+
+    /**
+     * 备注说明
+     */
+    private String remark;
+
+
+}

+ 90 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormFieldsBo.java

@@ -0,0 +1,90 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyFormFields;
+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.*;
+
+/**
+ * 万能单字段业务对象 ns_diy_form_fields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyFormFields.class, reverseConvertGenerate = false)
+public class NsDiyFormFieldsBo extends BaseEntity {
+
+    /**
+     * 字段id
+     */
+    private Long fieldId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 字段唯一标识
+     */
+    private String fieldKey;
+
+    /**
+     * 字段类型
+     */
+    private String fieldType;
+
+    /**
+     * 字段名称
+     */
+    private String fieldName;
+
+    /**
+     * 字段说明
+     */
+    private String fieldRemark;
+
+    /**
+     * 字段默认值
+     */
+    //@NotBlank(message = "字段默认值不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String fieldDefault;
+
+    /**
+     * 字段填写总数量
+     */
+    private Long writeNum;
+
+    /**
+     * 字段是否必填 0:否 1:是
+     */
+    private Long fieldRequired;
+
+    /**
+     * 字段是否隐藏 0:否 1:是
+     */
+    private Long fieldHidden;
+
+    /**
+     * 字段内容防重复 0:否 1:是
+     */
+    private Long fieldUnique;
+
+    /**
+     * 隐私保护 0:关闭 1:开启
+     */
+    private Long privacyProtection;
+
+
+}

+ 55 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormRecordsBo.java

@@ -0,0 +1,55 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyFormRecords;
+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.*;
+
+/**
+ * 万能单填写记录业务对象 ns_diy_form_records
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyFormRecords.class, reverseConvertGenerate = false)
+public class NsDiyFormRecordsBo extends BaseEntity {
+
+    /**
+     * 表单填写记录id
+     */
+    private Long recordId;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 填写的表单数据
+     */
+    //@NotBlank(message = "填写的表单数据不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String value;
+
+    /**
+     * 填写人会员id
+     */
+    private Long memberId;
+
+    /**
+     * 关联业务id
+     */
+    private Long relateId;
+
+
+}

+ 99 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormRecordsFieldsBo.java

@@ -0,0 +1,99 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyFormRecordsFields;
+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.*;
+
+/**
+ * 万能单填写字段业务对象 ns_diy_form_records_fields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyFormRecordsFields.class, reverseConvertGenerate = false)
+public class NsDiyFormRecordsFieldsBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 关联表单字段id
+     */
+    private Long formFieldId;
+
+    /**
+     * 关联表单填写记录id
+     */
+    private Long recordId;
+
+    /**
+     * 填写会员id
+     */
+    private Long memberId;
+
+    /**
+     * 字段唯一标识
+     */
+    private String fieldKey;
+
+    /**
+     * 字段类型
+     */
+    private String fieldType;
+
+    /**
+     * 字段名称
+     */
+    private String fieldName;
+
+    /**
+     * 字段值,根据类型展示对应效果
+     */
+    private String fieldValue;
+
+    /**
+     * 字段是否必填 0:否 1:是
+     */
+    private Long fieldRequired;
+
+    /**
+     * 字段是否隐藏 0:否 1:是
+     */
+    private Long fieldHidden;
+
+    /**
+     * 字段内容防重复 0:否 1:是
+     */
+    private Long fieldUnique;
+
+    /**
+     * 隐私保护 0:关闭 1:开启
+     */
+    private Long privacyProtection;
+
+    /**
+     * 字段修改次数
+     */
+    private Long updateNum;
+
+
+}

+ 77 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormSubmitConfigBo.java

@@ -0,0 +1,77 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyFormSubmitConfig;
+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.*;
+
+/**
+ * 万能单提交页配置业务对象 ns_diy_form_submit_config
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyFormSubmitConfig.class, reverseConvertGenerate = false)
+public class NsDiyFormSubmitConfigBo extends BaseEntity {
+
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 填表人提交后操作,text:文字信息,voucher:核销凭证
+     */
+    private String submitAfterAction;
+
+    /**
+     * 提示内容类型,default:默认提示,diy:自定义提示
+     */
+    private String tipsType;
+
+    /**
+     * 自定义提示内容
+     */
+    private String tipsText;
+
+    /**
+     * 核销凭证有效期限制类型,no_limit:不限制,specify_time:指定固定开始结束时间,submission_time:按提交时间设置有效期
+     */
+    private String timeLimitType;
+
+    /**
+     * 核销凭证时间限制规则,json格式
+     */
+    //@NotBlank(message = "核销凭证时间限制规则,json格式不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String timeLimitRule;
+
+    /**
+     * 核销凭证内容,json格式
+     */
+    //@NotBlank(message = "核销凭证内容,json格式不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String voucherContentRule;
+
+    /**
+     * 填写成功后续操作
+     */
+    //@NotBlank(message = "填写成功后续操作不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String successAfterAction;
+
+
+}

+ 102 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyFormWriteConfigBo.java

@@ -0,0 +1,102 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyFormWriteConfig;
+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.*;
+
+/**
+ * 万能单填写配置业务对象 ns_diy_form_write_config
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyFormWriteConfig.class, reverseConvertGenerate = false)
+public class NsDiyFormWriteConfigBo extends BaseEntity {
+
+    /**
+     * 主键id
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    private Long formId;
+
+    /**
+     * 填写方式,no_limit:不限制,scan:仅限微信扫一扫,url:仅限链接进入
+     */
+    private String writeWay;
+
+    /**
+     * 参与会员,all_member:所有会员参与,selected_member_level:指定会员等级,selected_member_label:指定会员标签
+     */
+    private String joinMemberType;
+
+    /**
+     * 会员等级id集合
+     */
+    //@NotBlank(message = "会员等级id集合不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String levelIds;
+
+    /**
+     * 会员标签id集合
+     */
+    //@NotBlank(message = "会员标签id集合不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String labelIds;
+
+    /**
+     * 每人可填写次数,no_limit:不限制,diy:自定义
+     */
+    private String memberWriteType;
+
+    /**
+     * 每人可填写次数自定义规则
+     */
+    private String memberWriteRule;
+
+    /**
+     * 表单可填写数量,no_limit:不限制,diy:自定义
+     */
+    private String formWriteType;
+
+    /**
+     * 表单可填写总数自定义规则
+     */
+    private String formWriteRule;
+
+    /**
+     * 填写时间限制类型,no_limit:不限制, specify_time:指定开始结束时间,open_day_time:设置每日开启时间
+     */
+    private String timeLimitType;
+
+    /**
+     * 填写时间限制规则
+     */
+    private String timeLimitRule;
+
+    /**
+     * 是否允许修改自己填写的内容,0:否,1:是
+     */
+    private Long isAllowUpdateContent;
+
+    /**
+     * 表单填写须知
+     */
+    //@NotBlank(message = "表单填写须知不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String writeInstruction;
+
+
+}

+ 90 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/bo/NsDiyPageBo.java

@@ -0,0 +1,90 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyPage;
+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.*;
+
+/**
+ * 自定义页面业务对象 ns_diy_page
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyPage.class, reverseConvertGenerate = false)
+public class NsDiyPageBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 页面名称(用于后台展示)
+     */
+    private String pageTitle;
+
+    /**
+     * 页面标题(用于前台展示)
+     */
+    private String title;
+
+    /**
+     * 页面标识
+     */
+    private String name;
+
+    /**
+     * 页面模板
+     */
+    private String type;
+
+    /**
+     * 模板名称
+     */
+    private String template;
+
+    /**
+     * 页面展示模式,diy:自定义,fixed:固定
+     */
+    private String mode;
+
+    /**
+     * 页面数据,json格式
+     */
+    //@NotBlank(message = "页面数据,json格式不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String value;
+
+    /**
+     * 是否默认页面,1:是,0:否
+     */
+    private Long isDefault;
+
+    /**
+     * 数据是否发生过变化,1:变化了,2:没有
+     */
+    private Long isChange;
+
+    /**
+     * 分享内容
+     */
+    private String share;
+
+    /**
+     * 访问量
+     */
+    private Long visitCount;
+
+
+}

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

@@ -0,0 +1,64 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyRoute;
+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.*;
+
+/**
+ * 自定义路由业务对象 ns_diy_route
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyRoute.class, reverseConvertGenerate = false)
+public class NsDiyRouteBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 页面名称
+     */
+    private String title;
+
+    /**
+     * 页面标识
+     */
+    private String name;
+
+    /**
+     * 页面路径
+     */
+    private String page;
+
+    /**
+     * 分享内容
+     */
+    private String share;
+
+    /**
+     * 是否支持分享
+     */
+    private Long isShare;
+
+    /**
+     * 排序
+     */
+    private Long sort;
+
+
+}

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

@@ -0,0 +1,82 @@
+package org.dromara.mall.domain.bo;
+
+import org.dromara.mall.domain.NsDiyTheme;
+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.*;
+
+/**
+ * 自定义主题配色业务对象 ns_diy_theme
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@AutoMapper(target = NsDiyTheme.class, reverseConvertGenerate = false)
+public class NsDiyThemeBo extends BaseEntity {
+
+    /**
+     * 
+     */
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    private Long siteId;
+
+    /**
+     * 颜色名称
+     */
+    private String title;
+
+    /**
+     * 插件类型app,addon
+     */
+    private String type;
+
+    /**
+     * 所属应用,app:系统,shop:商城、o2o:上门服务
+     */
+    private String addon;
+
+    /**
+     * 模式,default:默认【跟随系统】,diy:自定义配色
+     */
+    private String mode;
+
+    /**
+     * 配色类型,default:默认,diy:自定义
+     */
+    private String themeType;
+
+    /**
+     * 当前色调的默认值
+     */
+    //@NotBlank(message = "当前色调的默认值不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String defaultTheme;
+
+    /**
+     * 当前色调
+     */
+    //@NotBlank(message = "当前色调不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String theme;
+
+    /**
+     * 新增颜色集合
+     */
+    //@NotBlank(message = "新增颜色集合不能为空", groups = { AddGroup.class, EditGroup.class })
+    private String newTheme;
+
+    /**
+     * 已选色调,0:否,1.是
+     */
+    private Long isSelected;
+
+
+}

+ 41 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyAdvParam.java

@@ -0,0 +1,41 @@
+package org.dromara.mall.domain.param;
+
+import cn.hutool.json.JSONObject;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 广告表参数
+*/
+@Data
+public class DiyAdvParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Integer advId;
+
+    /** 广告位key */
+    private String advKey;
+
+    /** 广告内容描述 */
+    private String advTitle;
+
+    /** 广告链接 */
+    private JSONObject advUrl;
+
+    /** 广告内容图片 */
+    private String advImage;
+
+
+    /** 背景色 */
+    private String background = "#FFFFFF";
+
+    private String apKey;
+
+    private Integer slideSort =0;
+
+
+
+}

+ 41 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyAdvSearchParam.java

@@ -0,0 +1,41 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 广告表参数
+ */
+@Data
+public class DiyAdvSearchParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Integer advId;
+
+    /** 广告位key */
+    private String advKey;
+
+    /** 广告位key */
+    private String apKey;
+
+    /** 广告内容描述 */
+    private String advTitle;
+
+    /** 广告链接 */
+    private String advUrl;
+
+    /** 广告内容图片 */
+    private String advImage;
+
+    /** 排序号 */
+    private Integer sort;
+
+    /** 背景色 */
+    private String background;
+    private  Integer slideSort;
+
+
+}

+ 24 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyAdvSortParam.java

@@ -0,0 +1,24 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 广告排序修改
+*/
+@Data
+public class DiyAdvSortParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    /** 主键 */
+    private Integer id;
+
+
+    /** 排序号 */
+    private Integer sort;
+
+
+
+}

+ 17 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyConfigParam.java

@@ -0,0 +1,17 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义页面参数
+*/
+@Data
+public class DiyConfigParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String key = "app";
+
+}

+ 20 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyLinkParam.java

@@ -0,0 +1,20 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 手机端链接
+*/
+@Data
+public class DiyLinkParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    private String type;
+
+
+
+}

+ 23 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyPageInitParam.java

@@ -0,0 +1,23 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义页面参数
+*/
+@Data
+public class DiyPageInitParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id = 0;
+
+    private String title = "";
+
+    private String name = "";
+
+    private String type = "";
+
+}

+ 45 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyPageParam.java

@@ -0,0 +1,45 @@
+package org.dromara.mall.domain.param;
+
+import jakarta.validation.constraints.NotBlank;
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义页面参数
+*/
+@Data
+public class DiyPageParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @NotNull(message = "pageTitle参数缺失")
+    private String pageTitle;
+
+    @NotNull(message = "title参数缺失")
+    private String title;
+
+    @NotNull(message = "name参数缺失")
+    private String name;
+
+    @NotNull(message = "type参数缺失")
+    private String type;
+
+    @NotNull(message = "template参数缺失")
+    private String template;
+
+    @NotNull(message = "mode参数缺失")
+    private String mode = "diy";
+
+    @NotBlank(message = "value不能为空")
+    @NotNull(message = "value参数缺失")
+    private String value;
+
+    @NotNull(message = "isDefault参数缺失")
+    private Integer isDefault = 0;
+
+    @NotNull(message = "isChange参数缺失")
+    private Integer isChange = 0;
+
+}

+ 24 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyPageSearchParam.java

@@ -0,0 +1,24 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义页面参数
+ */
+@Data
+public class DiyPageSearchParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+
+    private String title;
+
+    private String type;
+
+    private String mode;
+
+    private String addonName;
+
+}

+ 21 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyRouteSearchParam.java

@@ -0,0 +1,21 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义路由参数
+ */
+@Data
+public class DiyRouteSearchParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String title;
+
+    private String url;
+
+    private String addonName;
+
+}

+ 34 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyRouteShareParam.java

@@ -0,0 +1,34 @@
+package org.dromara.mall.domain.param;
+
+import jakarta.validation.constraints.NotNull;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义路由参数
+*/
+@Data
+public class DiyRouteShareParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    @NotNull(message = "title参数缺失")
+    private String title;
+
+    @NotNull(message = "name参数缺失")
+    private String name;
+
+    @NotNull(message = "page参数缺失")
+    private String page;
+
+    @NotNull(message = "share参数缺失")
+    private String share;
+
+    @NotNull(message = "isShare参数缺失")
+    private Integer isShare;
+
+    @NotNull(message = "sort参数缺失")
+    private Integer sort = 0;
+
+}

+ 18 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeColorParam.java

@@ -0,0 +1,18 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义主题色设置
+*/
+@Data
+public class DiyThemeColorParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String addon;
+
+
+}

+ 29 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeParam.java

@@ -0,0 +1,29 @@
+package org.dromara.mall.domain.param;
+
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义主题色设置
+*/
+@Data
+public class DiyThemeParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    private String addon;
+
+    private String title;
+
+    private JSONObject theme;
+
+    private JSONArray newTheme;
+
+    private JSONObject defaultTheme;
+
+}

+ 25 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeSetParam.java

@@ -0,0 +1,25 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义主题色设置
+*/
+@Data
+public class DiyThemeSetParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    private String addon;
+
+    private String title;
+
+    private Object theme;
+
+    private Object newTheme;
+
+}

+ 21 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/DiyThemeTitleParam.java

@@ -0,0 +1,21 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义主题色设置
+*/
+@Data
+public class DiyThemeTitleParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer id;
+
+    private String addon = "";
+
+    private String title = "";
+
+}

+ 27 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/SetDiyDataParam.java

@@ -0,0 +1,27 @@
+package org.dromara.mall.domain.param;
+
+import cn.hutool.json.JSONArray;
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义页面参数
+ */
+@Data
+public class SetDiyDataParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private Integer siteId;
+
+    private String key;
+
+    private String type = "";
+
+    private String addon = "";
+
+    private Integer isStart;
+
+    private JSONArray mainApp;
+}

+ 26 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/param/TemplateParam.java

@@ -0,0 +1,26 @@
+package org.dromara.mall.domain.param;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 自定义页面参数
+*/
+@Data
+public class TemplateParam implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String[] key;
+
+    private String action = "";
+
+    private String mode = "";
+
+    private String type = "";
+
+    private String appType = "";
+
+    private String addon = "";
+}

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

@@ -0,0 +1,87 @@
+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.NsDiyAdv;
+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;
+
+
+
+/**
+ * 广告视图对象 ns_diy_adv
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyAdv.class)
+public class NsDiyAdvVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键
+     */
+    @ExcelProperty(value = "主键")
+    private Long advId;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 广告位key
+     */
+    @ExcelProperty(value = "广告位key")
+    private String apKey;
+
+    /**
+     * 广告内容描述
+     */
+    @ExcelProperty(value = "广告内容描述")
+    private String advTitle;
+
+    /**
+     * 广告链接
+     */
+    @ExcelProperty(value = "广告链接")
+    private String advUrl;
+
+    /**
+     * 广告内容图片
+     */
+    @ExcelProperty(value = "广告内容图片")
+    private String advImage;
+
+    /**
+     * 广告内容图片Url
+     */
+    @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "advImage")
+    private String advImageUrl;
+    /**
+     * 排序号
+     */
+    @ExcelProperty(value = "排序号")
+    private Long slideSort;
+
+    /**
+     * 背景色
+     */
+    @ExcelProperty(value = "背景色")
+    private String background;
+
+
+}

+ 110 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormFieldsVo.java

@@ -0,0 +1,110 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyFormFields;
+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;
+
+
+
+/**
+ * 万能单字段视图对象 ns_diy_form_fields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyFormFields.class)
+public class NsDiyFormFieldsVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 字段id
+     */
+    @ExcelProperty(value = "字段id")
+    private Long fieldId;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    @ExcelProperty(value = "所属万能表单id")
+    private Long formId;
+
+    /**
+     * 字段唯一标识
+     */
+    @ExcelProperty(value = "字段唯一标识")
+    private String fieldKey;
+
+    /**
+     * 字段类型
+     */
+    @ExcelProperty(value = "字段类型")
+    private String fieldType;
+
+    /**
+     * 字段名称
+     */
+    @ExcelProperty(value = "字段名称")
+    private String fieldName;
+
+    /**
+     * 字段说明
+     */
+    @ExcelProperty(value = "字段说明")
+    private String fieldRemark;
+
+    /**
+     * 字段默认值
+     */
+    @ExcelProperty(value = "字段默认值")
+    private String fieldDefault;
+
+    /**
+     * 字段填写总数量
+     */
+    @ExcelProperty(value = "字段填写总数量")
+    private Long writeNum;
+
+    /**
+     * 字段是否必填 0:否 1:是
+     */
+    @ExcelProperty(value = "字段是否必填 0:否 1:是")
+    private Long fieldRequired;
+
+    /**
+     * 字段是否隐藏 0:否 1:是
+     */
+    @ExcelProperty(value = "字段是否隐藏 0:否 1:是")
+    private Long fieldHidden;
+
+    /**
+     * 字段内容防重复 0:否 1:是
+     */
+    @ExcelProperty(value = "字段内容防重复 0:否 1:是")
+    private Long fieldUnique;
+
+    /**
+     * 隐私保护 0:关闭 1:开启
+     */
+    @ExcelProperty(value = "隐私保护 0:关闭 1:开启")
+    private Long privacyProtection;
+
+
+}

+ 122 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormRecordsFieldsVo.java

@@ -0,0 +1,122 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyFormRecordsFields;
+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;
+
+
+
+/**
+ * 万能单填写字段视图对象 ns_diy_form_records_fields
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyFormRecordsFields.class)
+public class NsDiyFormRecordsFieldsVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    @ExcelProperty(value = "所属万能表单id")
+    private Long formId;
+
+    /**
+     * 关联表单字段id
+     */
+    @ExcelProperty(value = "关联表单字段id")
+    private Long formFieldId;
+
+    /**
+     * 关联表单填写记录id
+     */
+    @ExcelProperty(value = "关联表单填写记录id")
+    private Long recordId;
+
+    /**
+     * 填写会员id
+     */
+    @ExcelProperty(value = "填写会员id")
+    private Long memberId;
+
+    /**
+     * 字段唯一标识
+     */
+    @ExcelProperty(value = "字段唯一标识")
+    private String fieldKey;
+
+    /**
+     * 字段类型
+     */
+    @ExcelProperty(value = "字段类型")
+    private String fieldType;
+
+    /**
+     * 字段名称
+     */
+    @ExcelProperty(value = "字段名称")
+    private String fieldName;
+
+    /**
+     * 字段值,根据类型展示对应效果
+     */
+    @ExcelProperty(value = "字段值,根据类型展示对应效果")
+    private String fieldValue;
+
+    /**
+     * 字段是否必填 0:否 1:是
+     */
+    @ExcelProperty(value = "字段是否必填 0:否 1:是")
+    private Long fieldRequired;
+
+    /**
+     * 字段是否隐藏 0:否 1:是
+     */
+    @ExcelProperty(value = "字段是否隐藏 0:否 1:是")
+    private Long fieldHidden;
+
+    /**
+     * 字段内容防重复 0:否 1:是
+     */
+    @ExcelProperty(value = "字段内容防重复 0:否 1:是")
+    private Long fieldUnique;
+
+    /**
+     * 隐私保护 0:关闭 1:开启
+     */
+    @ExcelProperty(value = "隐私保护 0:关闭 1:开启")
+    private Long privacyProtection;
+
+    /**
+     * 字段修改次数
+     */
+    @ExcelProperty(value = "字段修改次数")
+    private Long updateNum;
+
+
+}

+ 68 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormRecordsVo.java

@@ -0,0 +1,68 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyFormRecords;
+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;
+
+
+
+/**
+ * 万能单填写记录视图对象 ns_diy_form_records
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyFormRecords.class)
+public class NsDiyFormRecordsVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表单填写记录id
+     */
+    @ExcelProperty(value = "表单填写记录id")
+    private Long recordId;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    @ExcelProperty(value = "所属万能表单id")
+    private Long formId;
+
+    /**
+     * 填写的表单数据
+     */
+    @ExcelProperty(value = "填写的表单数据")
+    private String value;
+
+    /**
+     * 填写人会员id
+     */
+    @ExcelProperty(value = "填写人会员id")
+    private Long memberId;
+
+    /**
+     * 关联业务id
+     */
+    @ExcelProperty(value = "关联业务id")
+    private Long relateId;
+
+
+}

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

@@ -0,0 +1,92 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyFormSubmitConfig;
+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;
+
+
+
+/**
+ * 万能单提交页配置视图对象 ns_diy_form_submit_config
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyFormSubmitConfig.class)
+public class NsDiyFormSubmitConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @ExcelProperty(value = "主键id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    @ExcelProperty(value = "所属万能表单id")
+    private Long formId;
+
+    /**
+     * 填表人提交后操作,text:文字信息,voucher:核销凭证
+     */
+    @ExcelProperty(value = "填表人提交后操作,text:文字信息,voucher:核销凭证")
+    private String submitAfterAction;
+
+    /**
+     * 提示内容类型,default:默认提示,diy:自定义提示
+     */
+    @ExcelProperty(value = "提示内容类型,default:默认提示,diy:自定义提示")
+    private String tipsType;
+
+    /**
+     * 自定义提示内容
+     */
+    @ExcelProperty(value = "自定义提示内容")
+    private String tipsText;
+
+    /**
+     * 核销凭证有效期限制类型,no_limit:不限制,specify_time:指定固定开始结束时间,submission_time:按提交时间设置有效期
+     */
+    @ExcelProperty(value = "核销凭证有效期限制类型,no_limit:不限制,specify_time:指定固定开始结束时间,submission_time:按提交时间设置有效期")
+    private String timeLimitType;
+
+    /**
+     * 核销凭证时间限制规则,json格式
+     */
+    @ExcelProperty(value = "核销凭证时间限制规则,json格式")
+    private String timeLimitRule;
+
+    /**
+     * 核销凭证内容,json格式
+     */
+    @ExcelProperty(value = "核销凭证内容,json格式")
+    private String voucherContentRule;
+
+    /**
+     * 填写成功后续操作
+     */
+    @ExcelProperty(value = "填写成功后续操作")
+    private String successAfterAction;
+
+
+}

+ 107 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormVo.java

@@ -0,0 +1,107 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyForm;
+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;
+
+
+
+/**
+ * 万能单视图对象 ns_diy_form
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyForm.class)
+public class NsDiyFormVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 表单id
+     */
+    @ExcelProperty(value = "表单id")
+    private Long formId;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 表单名称(用于后台展示)
+     */
+    @ExcelProperty(value = "表单名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "用=于后台展示")
+    private String pageTitle;
+
+    /**
+     * 表单名称(用于前台展示)
+     */
+    @ExcelProperty(value = "表单名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "用=于前台展示")
+    private String title;
+
+    /**
+     * 表单类型
+     */
+    @ExcelProperty(value = "表单类型")
+    private String type;
+
+    /**
+     * 状态(0,关闭,1:开启)
+     */
+    @ExcelProperty(value = "状态", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "0=,关闭,1:开启")
+    private Long status;
+
+    /**
+     * 模板名称
+     */
+    @ExcelProperty(value = "模板名称")
+    private String template;
+
+    /**
+     * 表单数据,json格式,包含展示组件
+     */
+    @ExcelProperty(value = "表单数据,json格式,包含展示组件")
+    private String value;
+
+    /**
+     * 所属插件标识
+     */
+    @ExcelProperty(value = "所属插件标识")
+    private String addon;
+
+    /**
+     * 分享内容
+     */
+    @ExcelProperty(value = "分享内容")
+    private String share;
+
+    /**
+     * 表单填写总数量
+     */
+    @ExcelProperty(value = "表单填写总数量")
+    private Long writeNum;
+
+    /**
+     * 备注说明
+     */
+    @ExcelProperty(value = "备注说明")
+    private String remark;
+
+
+}

+ 122 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyFormWriteConfigVo.java

@@ -0,0 +1,122 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyFormWriteConfig;
+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;
+
+
+
+/**
+ * 万能单填写配置视图对象 ns_diy_form_write_config
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyFormWriteConfig.class)
+public class NsDiyFormWriteConfigVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 主键id
+     */
+    @ExcelProperty(value = "主键id")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 所属万能表单id
+     */
+    @ExcelProperty(value = "所属万能表单id")
+    private Long formId;
+
+    /**
+     * 填写方式,no_limit:不限制,scan:仅限微信扫一扫,url:仅限链接进入
+     */
+    @ExcelProperty(value = "填写方式,no_limit:不限制,scan:仅限微信扫一扫,url:仅限链接进入")
+    private String writeWay;
+
+    /**
+     * 参与会员,all_member:所有会员参与,selected_member_level:指定会员等级,selected_member_label:指定会员标签
+     */
+    @ExcelProperty(value = "参与会员,all_member:所有会员参与,selected_member_level:指定会员等级,selected_member_label:指定会员标签")
+    private String joinMemberType;
+
+    /**
+     * 会员等级id集合
+     */
+    @ExcelProperty(value = "会员等级id集合")
+    private String levelIds;
+
+    /**
+     * 会员标签id集合
+     */
+    @ExcelProperty(value = "会员标签id集合")
+    private String labelIds;
+
+    /**
+     * 每人可填写次数,no_limit:不限制,diy:自定义
+     */
+    @ExcelProperty(value = "每人可填写次数,no_limit:不限制,diy:自定义")
+    private String memberWriteType;
+
+    /**
+     * 每人可填写次数自定义规则
+     */
+    @ExcelProperty(value = "每人可填写次数自定义规则")
+    private String memberWriteRule;
+
+    /**
+     * 表单可填写数量,no_limit:不限制,diy:自定义
+     */
+    @ExcelProperty(value = "表单可填写数量,no_limit:不限制,diy:自定义")
+    private String formWriteType;
+
+    /**
+     * 表单可填写总数自定义规则
+     */
+    @ExcelProperty(value = "表单可填写总数自定义规则")
+    private String formWriteRule;
+
+    /**
+     * 填写时间限制类型,no_limit:不限制, specify_time:指定开始结束时间,open_day_time:设置每日开启时间
+     */
+    @ExcelProperty(value = "填写时间限制类型,no_limit:不限制, specify_time:指定开始结束时间,open_day_time:设置每日开启时间")
+    private String timeLimitType;
+
+    /**
+     * 填写时间限制规则
+     */
+    @ExcelProperty(value = "填写时间限制规则")
+    private String timeLimitRule;
+
+    /**
+     * 是否允许修改自己填写的内容,0:否,1:是
+     */
+    @ExcelProperty(value = "是否允许修改自己填写的内容,0:否,1:是")
+    private Long isAllowUpdateContent;
+
+    /**
+     * 表单填写须知
+     */
+    @ExcelProperty(value = "表单填写须知")
+    private String writeInstruction;
+
+
+}

+ 122 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyPageVo.java

@@ -0,0 +1,122 @@
+package org.dromara.mall.domain.vo;
+
+import cn.hutool.json.JSONObject;
+import org.dromara.mall.domain.NsDiyPage;
+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;
+
+
+
+/**
+ * 自定义页面视图对象 ns_diy_page
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyPage.class)
+public class NsDiyPageVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 页面名称(用于后台展示)
+     */
+    @ExcelProperty(value = "页面名称", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "用=于后台展示")
+    private String pageTitle;
+
+    /**
+     * 页面标题(用于前台展示)
+     */
+    @ExcelProperty(value = "页面标题", converter = ExcelDictConvert.class)
+    @ExcelDictFormat(readConverterExp = "用=于前台展示")
+    private String title;
+
+    /**
+     * 页面标识
+     */
+    @ExcelProperty(value = "页面标识")
+    private String name;
+
+    /**
+     * 页面模板
+     */
+    @ExcelProperty(value = "页面模板")
+    private String type;
+
+    /**
+     * 模板名称
+     */
+    @ExcelProperty(value = "模板名称")
+    private String template;
+
+    /**
+     * 页面展示模式,diy:自定义,fixed:固定
+     */
+    @ExcelProperty(value = "页面展示模式,diy:自定义,fixed:固定")
+    private String mode;
+
+    /**
+     * 页面数据,json格式
+     */
+    @ExcelProperty(value = "页面数据,json格式")
+    private String value;
+
+    /**
+     * 是否默认页面,1:是,0:否
+     */
+    @ExcelProperty(value = "是否默认页面,1:是,0:否")
+    private Long isDefault;
+
+    /**
+     * 数据是否发生过变化,1:变化了,2:没有
+     */
+    @ExcelProperty(value = "数据是否发生过变化,1:变化了,2:没有")
+    private Long isChange;
+
+    /**
+     * 分享内容
+     */
+    @ExcelProperty(value = "分享内容")
+    private String share;
+
+    /**
+     * 访问量
+     */
+    @ExcelProperty(value = "访问量")
+    private Long visitCount;
+
+    private String typeName;
+    private String addonName;
+    private String typePage;
+
+    private String page;
+
+    private JSONObject component;
+    private SceneDomainVo domainUrl;
+
+
+}

+ 88 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyRouteVo.java

@@ -0,0 +1,88 @@
+package org.dromara.mall.domain.vo;
+
+import cn.hutool.json.JSONObject;
+import org.dromara.mall.domain.NsDiyRoute;
+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;
+
+
+
+/**
+ * 自定义路由视图对象 ns_diy_route
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyRoute.class)
+public class NsDiyRouteVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 页面名称
+     */
+    @ExcelProperty(value = "页面名称")
+    private String title;
+
+    /**
+     * 页面标识
+     */
+    @ExcelProperty(value = "页面标识")
+    private String name;
+
+    /**
+     * 页面路径
+     */
+    @ExcelProperty(value = "页面路径")
+    private String page;
+
+    /**
+     * 分享内容
+     */
+    @ExcelProperty(value = "分享内容")
+    private String share;
+
+    /**
+     * 是否支持分享
+     */
+    @ExcelProperty(value = "是否支持分享")
+    private Long isShare;
+
+    /**
+     * 排序
+     */
+    @ExcelProperty(value = "排序")
+    private Long sort;
+
+    private String parent;
+
+    private String action;
+
+    private JSONObject addonInfo;
+
+
+
+}

+ 98 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/NsDiyThemeVo.java

@@ -0,0 +1,98 @@
+package org.dromara.mall.domain.vo;
+
+import org.dromara.mall.domain.NsDiyTheme;
+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;
+
+
+
+/**
+ * 自定义主题配色视图对象 ns_diy_theme
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Data
+@ExcelIgnoreUnannotated
+@AutoMapper(target = NsDiyTheme.class)
+public class NsDiyThemeVo implements Serializable {
+
+    @Serial
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 
+     */
+    @ExcelProperty(value = "")
+    private Long id;
+
+    /**
+     * 站点id
+     */
+    @ExcelProperty(value = "站点id")
+    private Long siteId;
+
+    /**
+     * 颜色名称
+     */
+    @ExcelProperty(value = "颜色名称")
+    private String title;
+
+    /**
+     * 插件类型app,addon
+     */
+    @ExcelProperty(value = "插件类型app,addon")
+    private String type;
+
+    /**
+     * 所属应用,app:系统,shop:商城、o2o:上门服务
+     */
+    @ExcelProperty(value = "所属应用,app:系统,shop:商城、o2o:上门服务")
+    private String addon;
+
+    /**
+     * 模式,default:默认【跟随系统】,diy:自定义配色
+     */
+    @ExcelProperty(value = "模式,default:默认【跟随系统】,diy:自定义配色")
+    private String mode;
+
+    /**
+     * 配色类型,default:默认,diy:自定义
+     */
+    @ExcelProperty(value = "配色类型,default:默认,diy:自定义")
+    private String themeType;
+
+    /**
+     * 当前色调的默认值
+     */
+    @ExcelProperty(value = "当前色调的默认值")
+    private String defaultTheme;
+
+    /**
+     * 当前色调
+     */
+    @ExcelProperty(value = "当前色调")
+    private String theme;
+
+    /**
+     * 新增颜色集合
+     */
+    @ExcelProperty(value = "新增颜色集合")
+    private String newTheme;
+
+    /**
+     * 已选色调,0:否,1.是
+     */
+    @ExcelProperty(value = "已选色调,0:否,1.是")
+    private Long isSelected;
+
+
+}

+ 17 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/SceneDomainVo.java

@@ -0,0 +1,17 @@
+package org.dromara.mall.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+@Data
+public class SceneDomainVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String wapDomain;
+    /** 手机端域名 */
+    private String wapUrl;
+    /** web端域名 */
+    private String webUrl;
+}

+ 29 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/domain/vo/StartUpPageConfigVo.java

@@ -0,0 +1,29 @@
+package org.dromara.mall.domain.vo;
+
+import lombok.Data;
+
+import java.io.Serializable;
+
+/**
+ * 底部导航视图
+ */
+
+@Data
+public class StartUpPageConfigVo implements Serializable {
+
+    private static final long serialVersionUID = 1L;
+
+    private String type = "";
+
+    private String name = "";
+
+    private String mode = "";
+
+    private String title = "";
+
+    private String page = "";
+
+    private String parent = "";
+
+    private String action = "";
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyAdv;
+import org.dromara.mall.domain.vo.NsDiyAdvVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 广告Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyAdvMapper extends BaseMapperPlus<NsDiyAdv, NsDiyAdvVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyFormFields;
+import org.dromara.mall.domain.vo.NsDiyFormFieldsVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 万能单字段Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyFormFieldsMapper extends BaseMapperPlus<NsDiyFormFields, NsDiyFormFieldsVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyForm;
+import org.dromara.mall.domain.vo.NsDiyFormVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 万能单Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyFormMapper extends BaseMapperPlus<NsDiyForm, NsDiyFormVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyFormRecordsFields;
+import org.dromara.mall.domain.vo.NsDiyFormRecordsFieldsVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 万能单填写字段Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyFormRecordsFieldsMapper extends BaseMapperPlus<NsDiyFormRecordsFields, NsDiyFormRecordsFieldsVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyFormRecords;
+import org.dromara.mall.domain.vo.NsDiyFormRecordsVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 万能单填写记录Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyFormRecordsMapper extends BaseMapperPlus<NsDiyFormRecords, NsDiyFormRecordsVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyFormSubmitConfig;
+import org.dromara.mall.domain.vo.NsDiyFormSubmitConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 万能单提交页配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyFormSubmitConfigMapper extends BaseMapperPlus<NsDiyFormSubmitConfig, NsDiyFormSubmitConfigVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyFormWriteConfig;
+import org.dromara.mall.domain.vo.NsDiyFormWriteConfigVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 万能单填写配置Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyFormWriteConfigMapper extends BaseMapperPlus<NsDiyFormWriteConfig, NsDiyFormWriteConfigVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyPage;
+import org.dromara.mall.domain.vo.NsDiyPageVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 自定义页面Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyPageMapper extends BaseMapperPlus<NsDiyPage, NsDiyPageVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyRoute;
+import org.dromara.mall.domain.vo.NsDiyRouteVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 自定义路由Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyRouteMapper extends BaseMapperPlus<NsDiyRoute, NsDiyRouteVo> {
+
+}

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

@@ -0,0 +1,15 @@
+package org.dromara.mall.mapper;
+
+import org.dromara.mall.domain.NsDiyTheme;
+import org.dromara.mall.domain.vo.NsDiyThemeVo;
+import org.dromara.common.mybatis.core.mapper.BaseMapperPlus;
+
+/**
+ * 自定义主题配色Mapper接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface NsDiyThemeMapper extends BaseMapperPlus<NsDiyTheme, NsDiyThemeVo> {
+
+}

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

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyAdv;
+import org.dromara.mall.domain.vo.NsDiyAdvVo;
+import org.dromara.mall.domain.bo.NsDiyAdvBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 广告Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyAdvService extends IService<NsDiyAdv>{
+
+    /**
+     * 查询广告
+     *
+     * @param advId 主键
+     * @return 广告
+     */
+    NsDiyAdvVo queryById(Long advId);
+
+    /**
+     * 分页查询广告列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 广告分页列表
+     */
+    TableDataInfo<NsDiyAdvVo> queryPageList(NsDiyAdvBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的广告列表
+     *
+     * @param bo 查询条件
+     * @return 广告列表
+     */
+    List<NsDiyAdvVo> queryList(NsDiyAdvBo bo);
+
+    /**
+     * 新增广告
+     *
+     * @param bo 广告
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyAdvBo bo);
+
+    /**
+     * 修改广告
+     *
+     * @param bo 广告
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyAdvBo 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/INsDiyFormFieldsService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyFormFields;
+import org.dromara.mall.domain.vo.NsDiyFormFieldsVo;
+import org.dromara.mall.domain.bo.NsDiyFormFieldsBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 万能单字段Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyFormFieldsService extends IService<NsDiyFormFields>{
+
+    /**
+     * 查询万能单字段
+     *
+     * @param fieldId 主键
+     * @return 万能单字段
+     */
+    NsDiyFormFieldsVo queryById(Long fieldId);
+
+    /**
+     * 分页查询万能单字段列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单字段分页列表
+     */
+    TableDataInfo<NsDiyFormFieldsVo> queryPageList(NsDiyFormFieldsBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的万能单字段列表
+     *
+     * @param bo 查询条件
+     * @return 万能单字段列表
+     */
+    List<NsDiyFormFieldsVo> queryList(NsDiyFormFieldsBo bo);
+
+    /**
+     * 新增万能单字段
+     *
+     * @param bo 万能单字段
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyFormFieldsBo bo);
+
+    /**
+     * 修改万能单字段
+     *
+     * @param bo 万能单字段
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyFormFieldsBo 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/INsDiyFormRecordsFieldsService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyFormRecordsFields;
+import org.dromara.mall.domain.vo.NsDiyFormRecordsFieldsVo;
+import org.dromara.mall.domain.bo.NsDiyFormRecordsFieldsBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 万能单填写字段Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyFormRecordsFieldsService extends IService<NsDiyFormRecordsFields>{
+
+    /**
+     * 查询万能单填写字段
+     *
+     * @param id 主键
+     * @return 万能单填写字段
+     */
+    NsDiyFormRecordsFieldsVo queryById(Long id);
+
+    /**
+     * 分页查询万能单填写字段列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单填写字段分页列表
+     */
+    TableDataInfo<NsDiyFormRecordsFieldsVo> queryPageList(NsDiyFormRecordsFieldsBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的万能单填写字段列表
+     *
+     * @param bo 查询条件
+     * @return 万能单填写字段列表
+     */
+    List<NsDiyFormRecordsFieldsVo> queryList(NsDiyFormRecordsFieldsBo bo);
+
+    /**
+     * 新增万能单填写字段
+     *
+     * @param bo 万能单填写字段
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyFormRecordsFieldsBo bo);
+
+    /**
+     * 修改万能单填写字段
+     *
+     * @param bo 万能单填写字段
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyFormRecordsFieldsBo 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/INsDiyFormRecordsService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyFormRecords;
+import org.dromara.mall.domain.vo.NsDiyFormRecordsVo;
+import org.dromara.mall.domain.bo.NsDiyFormRecordsBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 万能单填写记录Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyFormRecordsService extends IService<NsDiyFormRecords>{
+
+    /**
+     * 查询万能单填写记录
+     *
+     * @param recordId 主键
+     * @return 万能单填写记录
+     */
+    NsDiyFormRecordsVo queryById(Long recordId);
+
+    /**
+     * 分页查询万能单填写记录列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单填写记录分页列表
+     */
+    TableDataInfo<NsDiyFormRecordsVo> queryPageList(NsDiyFormRecordsBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的万能单填写记录列表
+     *
+     * @param bo 查询条件
+     * @return 万能单填写记录列表
+     */
+    List<NsDiyFormRecordsVo> queryList(NsDiyFormRecordsBo bo);
+
+    /**
+     * 新增万能单填写记录
+     *
+     * @param bo 万能单填写记录
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyFormRecordsBo bo);
+
+    /**
+     * 修改万能单填写记录
+     *
+     * @param bo 万能单填写记录
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyFormRecordsBo 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/INsDiyFormService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyForm;
+import org.dromara.mall.domain.vo.NsDiyFormVo;
+import org.dromara.mall.domain.bo.NsDiyFormBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 万能单Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyFormService extends IService<NsDiyForm>{
+
+    /**
+     * 查询万能单
+     *
+     * @param formId 主键
+     * @return 万能单
+     */
+    NsDiyFormVo queryById(Long formId);
+
+    /**
+     * 分页查询万能单列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单分页列表
+     */
+    TableDataInfo<NsDiyFormVo> queryPageList(NsDiyFormBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的万能单列表
+     *
+     * @param bo 查询条件
+     * @return 万能单列表
+     */
+    List<NsDiyFormVo> queryList(NsDiyFormBo bo);
+
+    /**
+     * 新增万能单
+     *
+     * @param bo 万能单
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyFormBo bo);
+
+    /**
+     * 修改万能单
+     *
+     * @param bo 万能单
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyFormBo 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/INsDiyFormSubmitConfigService.java

@@ -0,0 +1,70 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyFormSubmitConfig;
+import org.dromara.mall.domain.vo.NsDiyFormSubmitConfigVo;
+import org.dromara.mall.domain.bo.NsDiyFormSubmitConfigBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 万能单提交页配置Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyFormSubmitConfigService extends IService<NsDiyFormSubmitConfig>{
+
+    /**
+     * 查询万能单提交页配置
+     *
+     * @param id 主键
+     * @return 万能单提交页配置
+     */
+    NsDiyFormSubmitConfigVo queryById(Long id);
+
+    /**
+     * 分页查询万能单提交页配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单提交页配置分页列表
+     */
+    TableDataInfo<NsDiyFormSubmitConfigVo> queryPageList(NsDiyFormSubmitConfigBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的万能单提交页配置列表
+     *
+     * @param bo 查询条件
+     * @return 万能单提交页配置列表
+     */
+    List<NsDiyFormSubmitConfigVo> queryList(NsDiyFormSubmitConfigBo bo);
+
+    /**
+     * 新增万能单提交页配置
+     *
+     * @param bo 万能单提交页配置
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyFormSubmitConfigBo bo);
+
+    /**
+     * 修改万能单提交页配置
+     *
+     * @param bo 万能单提交页配置
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyFormSubmitConfigBo 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/INsDiyFormWriteConfigService.java

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

+ 112 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyPageService.java

@@ -0,0 +1,112 @@
+package org.dromara.mall.service;
+
+import cn.hutool.json.JSONObject;
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyPage;
+import org.dromara.mall.domain.param.DiyPageInitParam;
+import org.dromara.mall.domain.param.DiyPageSearchParam;
+import org.dromara.mall.domain.param.TemplateParam;
+import org.dromara.mall.domain.vo.NsDiyPageVo;
+import org.dromara.mall.domain.bo.NsDiyPageBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 自定义页面Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyPageService extends IService<NsDiyPage>{
+
+    /**
+     * 查询自定义页面
+     *
+     * @param id 主键
+     * @return 自定义页面
+     */
+    NsDiyPageVo queryById(Long id);
+
+    /**
+     * 分页查询自定义页面列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 自定义页面分页列表
+     */
+    TableDataInfo<NsDiyPageVo> queryPageList(NsDiyPageBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的自定义页面列表
+     *
+     * @param bo 查询条件
+     * @return 自定义页面列表
+     */
+    List<NsDiyPageVo> queryList(NsDiyPageBo bo);
+
+    /**
+     * 新增自定义页面
+     *
+     * @param bo 自定义页面
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyPageBo bo);
+
+    /**
+     * 修改自定义页面
+     *
+     * @param bo 自定义页面
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyPageBo bo);
+
+    /**
+     * 校验并批量删除自定义页面信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 自定义页面详情
+     *
+     * @param name
+     * @return
+     */
+    NsDiyPageVo infoByName(String name);
+
+    /**
+     * 获取页面模板
+     * @param param
+     * @return
+     */
+    JSONObject getTemplate(TemplateParam param);
+
+    /**
+     * 获取页面列表
+     * @param searchParam
+     * @param pageQuery
+     * @return
+     */
+    TableDataInfo<NsDiyPageVo> getDiyPage(DiyPageSearchParam searchParam, PageQuery pageQuery);
+
+
+    /**
+     * 获取页面装修列表
+     * @param searchParam
+     * @return
+     */
+    JSONObject getDecoratePage(DiyPageSearchParam searchParam);
+
+    /**
+     * 页面初始化数据
+     * @param
+     * @return
+     */
+    NsDiyPageVo getPageInit(DiyPageInitParam param);
+}

+ 79 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/INsDiyRouteService.java

@@ -0,0 +1,79 @@
+package org.dromara.mall.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import org.dromara.mall.domain.NsDiyRoute;
+import org.dromara.mall.domain.param.DiyRouteSearchParam;
+import org.dromara.mall.domain.vo.NsDiyRouteVo;
+import org.dromara.mall.domain.bo.NsDiyRouteBo;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * 自定义路由Service接口
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+public interface INsDiyRouteService extends IService<NsDiyRoute>{
+
+    /**
+     * 查询自定义路由
+     *
+     * @param id 主键
+     * @return 自定义路由
+     */
+    NsDiyRouteVo queryById(Long id);
+
+    /**
+     * 分页查询自定义路由列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 自定义路由分页列表
+     */
+    TableDataInfo<NsDiyRouteVo> queryPageList(NsDiyRouteBo bo, PageQuery pageQuery);
+
+    /**
+     * 查询符合条件的自定义路由列表
+     *
+     * @param bo 查询条件
+     * @return 自定义路由列表
+     */
+    List<NsDiyRouteVo> queryList(NsDiyRouteBo bo);
+
+    /**
+     * 新增自定义路由
+     *
+     * @param bo 自定义路由
+     * @return 是否新增成功
+     */
+    Boolean insertByBo(NsDiyRouteBo bo);
+
+    /**
+     * 修改自定义路由
+     *
+     * @param bo 自定义路由
+     * @return 是否修改成功
+     */
+    Boolean updateByBo(NsDiyRouteBo bo);
+
+    /**
+     * 校验并批量删除自定义路由信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid);
+
+    /**
+     * 自定义路由列表
+     *
+     * @param searchParam 搜索参数
+     * @return PageResult<DiyRouteListedVo>
+     */
+    List<NsDiyRouteVo> list(DiyRouteSearchParam searchParam);
+}

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

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

+ 139 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyAdvServiceImpl.java

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

+ 144 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormFieldsServiceImpl.java

@@ -0,0 +1,144 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyFormFieldsBo;
+import org.dromara.mall.domain.vo.NsDiyFormFieldsVo;
+import org.dromara.mall.domain.NsDiyFormFields;
+import org.dromara.mall.mapper.NsDiyFormFieldsMapper;
+import org.dromara.mall.service.INsDiyFormFieldsService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 万能单字段Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyFormFieldsServiceImpl  extends ServiceImpl<NsDiyFormFieldsMapper, NsDiyFormFields> implements INsDiyFormFieldsService {
+
+    private final NsDiyFormFieldsMapper baseMapper;
+
+    /**
+     * 查询万能单字段
+     *
+     * @param fieldId 主键
+     * @return 万能单字段
+     */
+    @Override
+    public NsDiyFormFieldsVo queryById(Long fieldId){
+        return baseMapper.selectVoById(fieldId);
+    }
+
+    /**
+     * 分页查询万能单字段列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单字段分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyFormFieldsVo> queryPageList(NsDiyFormFieldsBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyFormFields> lqw = buildQueryWrapper(bo);
+        Page<NsDiyFormFieldsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的万能单字段列表
+     *
+     * @param bo 查询条件
+     * @return 万能单字段列表
+     */
+    @Override
+    public List<NsDiyFormFieldsVo> queryList(NsDiyFormFieldsBo bo) {
+        LambdaQueryWrapper<NsDiyFormFields> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyFormFields> buildQueryWrapper(NsDiyFormFieldsBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyFormFields> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyFormFields::getFieldId);
+        lqw.eq(bo.getSiteId() != null, NsDiyFormFields::getSiteId, bo.getSiteId());
+        lqw.eq(bo.getFormId() != null, NsDiyFormFields::getFormId, bo.getFormId());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldKey()), NsDiyFormFields::getFieldKey, bo.getFieldKey());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldType()), NsDiyFormFields::getFieldType, bo.getFieldType());
+        lqw.like(StringUtils.isNotBlank(bo.getFieldName()), NsDiyFormFields::getFieldName, bo.getFieldName());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldRemark()), NsDiyFormFields::getFieldRemark, bo.getFieldRemark());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldDefault()), NsDiyFormFields::getFieldDefault, bo.getFieldDefault());
+        lqw.eq(bo.getWriteNum() != null, NsDiyFormFields::getWriteNum, bo.getWriteNum());
+        lqw.eq(bo.getFieldRequired() != null, NsDiyFormFields::getFieldRequired, bo.getFieldRequired());
+        lqw.eq(bo.getFieldHidden() != null, NsDiyFormFields::getFieldHidden, bo.getFieldHidden());
+        lqw.eq(bo.getFieldUnique() != null, NsDiyFormFields::getFieldUnique, bo.getFieldUnique());
+        lqw.eq(bo.getPrivacyProtection() != null, NsDiyFormFields::getPrivacyProtection, bo.getPrivacyProtection());
+        return lqw;
+    }
+
+    /**
+     * 新增万能单字段
+     *
+     * @param bo 万能单字段
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyFormFieldsBo bo) {
+        NsDiyFormFields add = MapstructUtils.convert(bo, NsDiyFormFields.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setFieldId(add.getFieldId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改万能单字段
+     *
+     * @param bo 万能单字段
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyFormFieldsBo bo) {
+        NsDiyFormFields update = MapstructUtils.convert(bo, NsDiyFormFields.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyFormFields entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除万能单字段信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 146 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormRecordsFieldsServiceImpl.java

@@ -0,0 +1,146 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyFormRecordsFieldsBo;
+import org.dromara.mall.domain.vo.NsDiyFormRecordsFieldsVo;
+import org.dromara.mall.domain.NsDiyFormRecordsFields;
+import org.dromara.mall.mapper.NsDiyFormRecordsFieldsMapper;
+import org.dromara.mall.service.INsDiyFormRecordsFieldsService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 万能单填写字段Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyFormRecordsFieldsServiceImpl  extends ServiceImpl<NsDiyFormRecordsFieldsMapper, NsDiyFormRecordsFields> implements INsDiyFormRecordsFieldsService {
+
+    private final NsDiyFormRecordsFieldsMapper baseMapper;
+
+    /**
+     * 查询万能单填写字段
+     *
+     * @param id 主键
+     * @return 万能单填写字段
+     */
+    @Override
+    public NsDiyFormRecordsFieldsVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询万能单填写字段列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单填写字段分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyFormRecordsFieldsVo> queryPageList(NsDiyFormRecordsFieldsBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyFormRecordsFields> lqw = buildQueryWrapper(bo);
+        Page<NsDiyFormRecordsFieldsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的万能单填写字段列表
+     *
+     * @param bo 查询条件
+     * @return 万能单填写字段列表
+     */
+    @Override
+    public List<NsDiyFormRecordsFieldsVo> queryList(NsDiyFormRecordsFieldsBo bo) {
+        LambdaQueryWrapper<NsDiyFormRecordsFields> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyFormRecordsFields> buildQueryWrapper(NsDiyFormRecordsFieldsBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyFormRecordsFields> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyFormRecordsFields::getId);
+        lqw.eq(bo.getSiteId() != null, NsDiyFormRecordsFields::getSiteId, bo.getSiteId());
+        lqw.eq(bo.getFormId() != null, NsDiyFormRecordsFields::getFormId, bo.getFormId());
+        lqw.eq(bo.getFormFieldId() != null, NsDiyFormRecordsFields::getFormFieldId, bo.getFormFieldId());
+        lqw.eq(bo.getRecordId() != null, NsDiyFormRecordsFields::getRecordId, bo.getRecordId());
+        lqw.eq(bo.getMemberId() != null, NsDiyFormRecordsFields::getMemberId, bo.getMemberId());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldKey()), NsDiyFormRecordsFields::getFieldKey, bo.getFieldKey());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldType()), NsDiyFormRecordsFields::getFieldType, bo.getFieldType());
+        lqw.like(StringUtils.isNotBlank(bo.getFieldName()), NsDiyFormRecordsFields::getFieldName, bo.getFieldName());
+        lqw.eq(StringUtils.isNotBlank(bo.getFieldValue()), NsDiyFormRecordsFields::getFieldValue, bo.getFieldValue());
+        lqw.eq(bo.getFieldRequired() != null, NsDiyFormRecordsFields::getFieldRequired, bo.getFieldRequired());
+        lqw.eq(bo.getFieldHidden() != null, NsDiyFormRecordsFields::getFieldHidden, bo.getFieldHidden());
+        lqw.eq(bo.getFieldUnique() != null, NsDiyFormRecordsFields::getFieldUnique, bo.getFieldUnique());
+        lqw.eq(bo.getPrivacyProtection() != null, NsDiyFormRecordsFields::getPrivacyProtection, bo.getPrivacyProtection());
+        lqw.eq(bo.getUpdateNum() != null, NsDiyFormRecordsFields::getUpdateNum, bo.getUpdateNum());
+        return lqw;
+    }
+
+    /**
+     * 新增万能单填写字段
+     *
+     * @param bo 万能单填写字段
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyFormRecordsFieldsBo bo) {
+        NsDiyFormRecordsFields add = MapstructUtils.convert(bo, NsDiyFormRecordsFields.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改万能单填写字段
+     *
+     * @param bo 万能单填写字段
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyFormRecordsFieldsBo bo) {
+        NsDiyFormRecordsFields update = MapstructUtils.convert(bo, NsDiyFormRecordsFields.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyFormRecordsFields entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除万能单填写字段信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 137 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormRecordsServiceImpl.java

@@ -0,0 +1,137 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyFormRecordsBo;
+import org.dromara.mall.domain.vo.NsDiyFormRecordsVo;
+import org.dromara.mall.domain.NsDiyFormRecords;
+import org.dromara.mall.mapper.NsDiyFormRecordsMapper;
+import org.dromara.mall.service.INsDiyFormRecordsService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 万能单填写记录Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyFormRecordsServiceImpl  extends ServiceImpl<NsDiyFormRecordsMapper, NsDiyFormRecords> implements INsDiyFormRecordsService {
+
+    private final NsDiyFormRecordsMapper baseMapper;
+
+    /**
+     * 查询万能单填写记录
+     *
+     * @param recordId 主键
+     * @return 万能单填写记录
+     */
+    @Override
+    public NsDiyFormRecordsVo queryById(Long recordId){
+        return baseMapper.selectVoById(recordId);
+    }
+
+    /**
+     * 分页查询万能单填写记录列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单填写记录分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyFormRecordsVo> queryPageList(NsDiyFormRecordsBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyFormRecords> lqw = buildQueryWrapper(bo);
+        Page<NsDiyFormRecordsVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的万能单填写记录列表
+     *
+     * @param bo 查询条件
+     * @return 万能单填写记录列表
+     */
+    @Override
+    public List<NsDiyFormRecordsVo> queryList(NsDiyFormRecordsBo bo) {
+        LambdaQueryWrapper<NsDiyFormRecords> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyFormRecords> buildQueryWrapper(NsDiyFormRecordsBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyFormRecords> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyFormRecords::getRecordId);
+        lqw.eq(bo.getSiteId() != null, NsDiyFormRecords::getSiteId, bo.getSiteId());
+        lqw.eq(bo.getFormId() != null, NsDiyFormRecords::getFormId, bo.getFormId());
+        lqw.eq(StringUtils.isNotBlank(bo.getValue()), NsDiyFormRecords::getValue, bo.getValue());
+        lqw.eq(bo.getMemberId() != null, NsDiyFormRecords::getMemberId, bo.getMemberId());
+        lqw.eq(bo.getRelateId() != null, NsDiyFormRecords::getRelateId, bo.getRelateId());
+        return lqw;
+    }
+
+    /**
+     * 新增万能单填写记录
+     *
+     * @param bo 万能单填写记录
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyFormRecordsBo bo) {
+        NsDiyFormRecords add = MapstructUtils.convert(bo, NsDiyFormRecords.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setRecordId(add.getRecordId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改万能单填写记录
+     *
+     * @param bo 万能单填写记录
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyFormRecordsBo bo) {
+        NsDiyFormRecords update = MapstructUtils.convert(bo, NsDiyFormRecords.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyFormRecords entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除万能单填写记录信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

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

@@ -0,0 +1,142 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyFormBo;
+import org.dromara.mall.domain.vo.NsDiyFormVo;
+import org.dromara.mall.domain.NsDiyForm;
+import org.dromara.mall.mapper.NsDiyFormMapper;
+import org.dromara.mall.service.INsDiyFormService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 万能单Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyFormServiceImpl  extends ServiceImpl<NsDiyFormMapper, NsDiyForm> implements INsDiyFormService {
+
+    private final NsDiyFormMapper baseMapper;
+
+    /**
+     * 查询万能单
+     *
+     * @param formId 主键
+     * @return 万能单
+     */
+    @Override
+    public NsDiyFormVo queryById(Long formId){
+        return baseMapper.selectVoById(formId);
+    }
+
+    /**
+     * 分页查询万能单列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyFormVo> queryPageList(NsDiyFormBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyForm> lqw = buildQueryWrapper(bo);
+        Page<NsDiyFormVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的万能单列表
+     *
+     * @param bo 查询条件
+     * @return 万能单列表
+     */
+    @Override
+    public List<NsDiyFormVo> queryList(NsDiyFormBo bo) {
+        LambdaQueryWrapper<NsDiyForm> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyForm> buildQueryWrapper(NsDiyFormBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyForm> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyForm::getFormId);
+        lqw.eq(bo.getSiteId() != null, NsDiyForm::getSiteId, bo.getSiteId());
+        lqw.eq(StringUtils.isNotBlank(bo.getPageTitle()), NsDiyForm::getPageTitle, bo.getPageTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), NsDiyForm::getTitle, bo.getTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), NsDiyForm::getType, bo.getType());
+        lqw.eq(bo.getStatus() != null, NsDiyForm::getStatus, bo.getStatus());
+        lqw.eq(StringUtils.isNotBlank(bo.getTemplate()), NsDiyForm::getTemplate, bo.getTemplate());
+        lqw.eq(StringUtils.isNotBlank(bo.getValue()), NsDiyForm::getValue, bo.getValue());
+        lqw.eq(StringUtils.isNotBlank(bo.getAddon()), NsDiyForm::getAddon, bo.getAddon());
+        lqw.eq(StringUtils.isNotBlank(bo.getShare()), NsDiyForm::getShare, bo.getShare());
+        lqw.eq(bo.getWriteNum() != null, NsDiyForm::getWriteNum, bo.getWriteNum());
+        return lqw;
+    }
+
+    /**
+     * 新增万能单
+     *
+     * @param bo 万能单
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyFormBo bo) {
+        NsDiyForm add = MapstructUtils.convert(bo, NsDiyForm.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setFormId(add.getFormId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改万能单
+     *
+     * @param bo 万能单
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyFormBo bo) {
+        NsDiyForm update = MapstructUtils.convert(bo, NsDiyForm.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyForm entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除万能单信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

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

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

+ 146 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyFormWriteConfigServiceImpl.java

@@ -0,0 +1,146 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyFormWriteConfigBo;
+import org.dromara.mall.domain.vo.NsDiyFormWriteConfigVo;
+import org.dromara.mall.domain.NsDiyFormWriteConfig;
+import org.dromara.mall.mapper.NsDiyFormWriteConfigMapper;
+import org.dromara.mall.service.INsDiyFormWriteConfigService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 万能单填写配置Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyFormWriteConfigServiceImpl  extends ServiceImpl<NsDiyFormWriteConfigMapper, NsDiyFormWriteConfig> implements INsDiyFormWriteConfigService {
+
+    private final NsDiyFormWriteConfigMapper baseMapper;
+
+    /**
+     * 查询万能单填写配置
+     *
+     * @param id 主键
+     * @return 万能单填写配置
+     */
+    @Override
+    public NsDiyFormWriteConfigVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询万能单填写配置列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 万能单填写配置分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyFormWriteConfigVo> queryPageList(NsDiyFormWriteConfigBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyFormWriteConfig> lqw = buildQueryWrapper(bo);
+        Page<NsDiyFormWriteConfigVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的万能单填写配置列表
+     *
+     * @param bo 查询条件
+     * @return 万能单填写配置列表
+     */
+    @Override
+    public List<NsDiyFormWriteConfigVo> queryList(NsDiyFormWriteConfigBo bo) {
+        LambdaQueryWrapper<NsDiyFormWriteConfig> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyFormWriteConfig> buildQueryWrapper(NsDiyFormWriteConfigBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyFormWriteConfig> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyFormWriteConfig::getId);
+        lqw.eq(bo.getSiteId() != null, NsDiyFormWriteConfig::getSiteId, bo.getSiteId());
+        lqw.eq(bo.getFormId() != null, NsDiyFormWriteConfig::getFormId, bo.getFormId());
+        lqw.eq(StringUtils.isNotBlank(bo.getWriteWay()), NsDiyFormWriteConfig::getWriteWay, bo.getWriteWay());
+        lqw.eq(StringUtils.isNotBlank(bo.getJoinMemberType()), NsDiyFormWriteConfig::getJoinMemberType, bo.getJoinMemberType());
+        lqw.eq(StringUtils.isNotBlank(bo.getLevelIds()), NsDiyFormWriteConfig::getLevelIds, bo.getLevelIds());
+        lqw.eq(StringUtils.isNotBlank(bo.getLabelIds()), NsDiyFormWriteConfig::getLabelIds, bo.getLabelIds());
+        lqw.eq(StringUtils.isNotBlank(bo.getMemberWriteType()), NsDiyFormWriteConfig::getMemberWriteType, bo.getMemberWriteType());
+        lqw.eq(StringUtils.isNotBlank(bo.getMemberWriteRule()), NsDiyFormWriteConfig::getMemberWriteRule, bo.getMemberWriteRule());
+        lqw.eq(StringUtils.isNotBlank(bo.getFormWriteType()), NsDiyFormWriteConfig::getFormWriteType, bo.getFormWriteType());
+        lqw.eq(StringUtils.isNotBlank(bo.getFormWriteRule()), NsDiyFormWriteConfig::getFormWriteRule, bo.getFormWriteRule());
+        lqw.eq(StringUtils.isNotBlank(bo.getTimeLimitType()), NsDiyFormWriteConfig::getTimeLimitType, bo.getTimeLimitType());
+        lqw.eq(StringUtils.isNotBlank(bo.getTimeLimitRule()), NsDiyFormWriteConfig::getTimeLimitRule, bo.getTimeLimitRule());
+        lqw.eq(bo.getIsAllowUpdateContent() != null, NsDiyFormWriteConfig::getIsAllowUpdateContent, bo.getIsAllowUpdateContent());
+        lqw.eq(StringUtils.isNotBlank(bo.getWriteInstruction()), NsDiyFormWriteConfig::getWriteInstruction, bo.getWriteInstruction());
+        return lqw;
+    }
+
+    /**
+     * 新增万能单填写配置
+     *
+     * @param bo 万能单填写配置
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyFormWriteConfigBo bo) {
+        NsDiyFormWriteConfig add = MapstructUtils.convert(bo, NsDiyFormWriteConfig.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改万能单填写配置
+     *
+     * @param bo 万能单填写配置
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyFormWriteConfigBo bo) {
+        NsDiyFormWriteConfig update = MapstructUtils.convert(bo, NsDiyFormWriteConfig.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyFormWriteConfig entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除万能单填写配置信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 509 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyPageServiceImpl.java

@@ -0,0 +1,509 @@
+package org.dromara.mall.service.impl;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.alibaba.fastjson2.JSONPath;
+import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
+import com.baomidou.mybatisplus.core.metadata.IPage;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.mall.domain.param.DiyPageInitParam;
+import org.dromara.mall.domain.param.DiyPageSearchParam;
+import org.dromara.mall.domain.param.DiyRouteSearchParam;
+import org.dromara.mall.domain.param.TemplateParam;
+import org.dromara.mall.domain.vo.NsDiyRouteVo;
+import org.dromara.mall.domain.vo.SceneDomainVo;
+import org.dromara.mall.domain.vo.StartUpPageConfigVo;
+import org.dromara.mall.service.INsDiyRouteService;
+import org.springframework.beans.BeanUtils;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyPageBo;
+import org.dromara.mall.domain.vo.NsDiyPageVo;
+import org.dromara.mall.domain.NsDiyPage;
+import org.dromara.mall.mapper.NsDiyPageMapper;
+import org.dromara.mall.service.INsDiyPageService;
+
+import java.net.URL;
+import java.util.*;
+
+/**
+ * 自定义页面Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyPageServiceImpl  extends ServiceImpl<NsDiyPageMapper, NsDiyPage> implements INsDiyPageService {
+
+    private final NsDiyPageMapper baseMapper;
+
+    private final INsDiyRouteService nsDiyRouteService;
+
+    /**
+     * 查询自定义页面
+     *
+     * @param id 主键
+     * @return 自定义页面
+     */
+    @Override
+    public NsDiyPageVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询自定义页面列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 自定义页面分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyPageVo> queryPageList(NsDiyPageBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyPage> lqw = buildQueryWrapper(bo);
+        Page<NsDiyPageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的自定义页面列表
+     *
+     * @param bo 查询条件
+     * @return 自定义页面列表
+     */
+    @Override
+    public List<NsDiyPageVo> queryList(NsDiyPageBo bo) {
+        LambdaQueryWrapper<NsDiyPage> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyPage> buildQueryWrapper(NsDiyPageBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyPage> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyPage::getId);
+        lqw.eq(bo.getSiteId() != null, NsDiyPage::getSiteId, bo.getSiteId());
+        lqw.eq(StringUtils.isNotBlank(bo.getPageTitle()), NsDiyPage::getPageTitle, bo.getPageTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), NsDiyPage::getTitle, bo.getTitle());
+        lqw.like(StringUtils.isNotBlank(bo.getName()), NsDiyPage::getName, bo.getName());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), NsDiyPage::getType, bo.getType());
+        lqw.eq(StringUtils.isNotBlank(bo.getTemplate()), NsDiyPage::getTemplate, bo.getTemplate());
+        lqw.eq(StringUtils.isNotBlank(bo.getMode()), NsDiyPage::getMode, bo.getMode());
+        lqw.eq(StringUtils.isNotBlank(bo.getValue()), NsDiyPage::getValue, bo.getValue());
+        lqw.eq(bo.getIsDefault() != null, NsDiyPage::getIsDefault, bo.getIsDefault());
+        lqw.eq(bo.getIsChange() != null, NsDiyPage::getIsChange, bo.getIsChange());
+        lqw.eq(StringUtils.isNotBlank(bo.getShare()), NsDiyPage::getShare, bo.getShare());
+        lqw.eq(bo.getVisitCount() != null, NsDiyPage::getVisitCount, bo.getVisitCount());
+        return lqw;
+    }
+
+    /**
+     * 新增自定义页面
+     *
+     * @param bo 自定义页面
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyPageBo bo) {
+        NsDiyPage add = MapstructUtils.convert(bo, NsDiyPage.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改自定义页面
+     *
+     * @param bo 自定义页面
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyPageBo bo) {
+        NsDiyPage update = MapstructUtils.convert(bo, NsDiyPage.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyPage 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 name
+     * @return
+     */
+    @Override
+    public NsDiyPageVo infoByName(String name) {
+        NsDiyPageVo nsDiyPageVo = baseMapper.selectVoOne(Wrappers.lambdaQuery(NsDiyPage.class)
+            .eq(NsDiyPage::getName, name)
+            .eq(NsDiyPage::getIsDefault, 1)
+            .eq(NsDiyPage::getSiteId, 0)
+        );
+        return nsDiyPageVo;
+    }
+
+
+    /**
+     * 获取页面列表
+     *
+     * @param searchParam
+     * @param pageQuery
+     * @return
+     */
+    @Override
+    public TableDataInfo<NsDiyPageVo> getDiyPage(DiyPageSearchParam searchParam, PageQuery pageQuery) {
+        QueryWrapper<NsDiyPage> queryWrapper = new QueryWrapper<>();
+        queryWrapper.eq("site_id", 0);
+        queryWrapper.orderByDesc("id");
+
+        if (ObjectUtil.isNotEmpty(searchParam.getTitle())) queryWrapper.like("title", searchParam.getTitle());
+        if (ObjectUtil.isNotEmpty(searchParam.getMode())) queryWrapper.eq("mode", searchParam.getMode());
+        if (ObjectUtil.isNotEmpty(searchParam.getType())) queryWrapper.eq("type", searchParam.getType());
+
+        //获取resource/json/loader/diy/template.json
+        String templateJsonStr = ResourceUtil.readUtf8Str("json/loader/diy/template.json");
+        JSONObject template = JSONUtil.parseObj(templateJsonStr);
+
+        IPage<NsDiyPageVo> iPage = baseMapper.selectVoPage(pageQuery.build(), queryWrapper);
+        for (NsDiyPageVo item : iPage.getRecords()) {
+            item.setTypeName(ObjectUtil.defaultIfNull(template.getByPath(item.getType() + ".title", String.class), ""));
+            item.setTypePage(ObjectUtil.defaultIfNull(template.getByPath(item.getType() + ".page", String.class), ""));
+        }
+        return TableDataInfo.build(iPage);
+    }
+
+    /**
+     * 获取页面模板
+     *
+     * @return
+     */
+    public JSONObject getTemplate(TemplateParam param) {
+
+        if (true) {
+            param.setAppType("admin");
+        } else {
+            param.setAppType("site");
+        }
+        //获取resource/json/loader/diy/template.json
+        String templateJsonStr = ResourceUtil.readUtf8Str("json/loader/diy/template.json");
+        JSONObject template = JSONUtil.parseObj(templateJsonStr);
+
+        for (String key : template.keySet()) {
+            JSONObject pages = ObjectUtil.defaultIfNull(getPages(key, param.getMode()), new JSONObject());
+            template.putByPath(key + ".template", pages);
+        }
+
+        return template;
+    }
+
+    public static JSONObject getPages(String type, String mode){
+        //获取resource/json/loader/diy/template.json
+        String pageJsonStr = ResourceUtil.readUtf8Str("json/loader/diy/pages.json");
+        JSONObject pages = JSONUtil.parseObj(pageJsonStr);
+
+        if (!type.isEmpty() && pages != null) {
+            pages = pages.getJSONObject(type);
+        }
+        if (!mode.isEmpty() && pages != null) {
+            JSONObject modePages = new JSONObject();
+            for (String key : pages.keySet()) {
+                if (!pages.getStr(key + ".mode", "").equals(mode)) {
+                    modePages.put(key, pages.getJSONObject(key));
+                }
+            }
+            return modePages;
+        }
+
+        return pages;
+    }
+
+    public static JSONObject getPagesByAddon(String type, String addon){
+        //获取resource/json/loader/diy/template.json
+        String pageJsonStr = ResourceUtil.readUtf8Str("json/loader/diy/pages.json");
+        JSONObject pages = JSONUtil.parseObj(pageJsonStr);
+
+        if (type != null && !type.isEmpty() && pages != null) {
+            pages = pages.getJSONObject(type);
+        }
+
+        return pages;
+    }
+
+    /**
+     * 获取默认页面数据
+     *
+     * @param type
+     * @param addon
+     * @return
+     */
+    public JSONObject getFirstPageData(String type, String addon) {
+        JSONObject pages = getPagesByAddon(type, addon);
+        if (pages == null || pages.keySet().size() == 0) return null;
+
+        String template = pages.keySet().iterator().next();
+        JSONObject data = pages.getJSONObject(template);
+        data.set("type", type);
+        data.set("template", template);
+
+        return data;
+    }
+
+    public static void main(String[] args) {
+        //获取resource/json/loader/diy/template.json
+        String jsonStr = ResourceUtil.readUtf8Str("json/loader/diy/template.json");
+        //jan
+        JSONObject template = JSONUtil.parseObj(jsonStr);
+        System.out.println(template.toStringPretty());
+    }
+
+    /**
+     * 获取页面装修列表
+     *
+     * @param searchParam
+     * @return
+     */
+    @Override
+    public JSONObject getDecoratePage(DiyPageSearchParam searchParam) {
+
+        TemplateParam templateParam = new TemplateParam();
+        String[] key = {searchParam.getType()};
+        templateParam.setKey(key);
+        JSONObject template = this.getTemplate(templateParam).getJSONObject(searchParam.getType());
+        if (template == null) throw new RuntimeException("模板不存在");
+
+        JSONObject defaultPage = getFirstPageData(searchParam.getType(), "");
+
+        JSONObject useTemplate = new JSONObject();
+        useTemplate.put("type", searchParam.getType());
+        useTemplate.put("title", defaultPage == null ? "" : defaultPage.getStr("title", ""));
+        useTemplate.put("name", "");
+        useTemplate.put("cover", defaultPage == null ? "" : defaultPage.getStr("cover", ""));
+        useTemplate.put("page", template.getStr("page"));
+        useTemplate.put("action", template.getStr("action"));
+        useTemplate.put("url", "");
+        useTemplate.put("parent", "");
+
+        NsDiyPageVo info = infoByName(searchParam.getType());
+        useTemplate.set("id", info.getId());
+        useTemplate.set("title", info.getTitle());
+        if (useTemplate.getStr("cover").isEmpty() && useTemplate.getStr("url").isEmpty()) {
+            useTemplate.set("url", template.getStr("page"));
+        } else if (useTemplate.getStr("url").isEmpty()) {
+            useTemplate.set("url", template.getStr("page"));
+        }
+
+        DiyRouteSearchParam diyRouteSearchParam = new DiyRouteSearchParam();
+        diyRouteSearchParam.setUrl(useTemplate.getStr("page"));
+        List<NsDiyRouteVo> otherPage = nsDiyRouteService.list(diyRouteSearchParam);
+        if (otherPage.size() > 0) {
+            NsDiyRouteVo route = otherPage.get(0);
+            useTemplate.set("title", route.getTitle());
+            useTemplate.set("name", route.getName());
+            useTemplate.set("parent", route.getParent());
+            useTemplate.set("action", route.getAction());
+        }
+
+        template.put("use_template", useTemplate);
+        String wapDomain = "http://127.0.0.1:8080";
+        SceneDomainVo sceneDomainVo = new SceneDomainVo();
+        sceneDomainVo.setWapDomain(wapDomain);
+        sceneDomainVo.setWapUrl(wapDomain + "/wap");
+        sceneDomainVo.setWebUrl(wapDomain + "/web");
+        JSONObject domainUrl = new JSONObject();
+        domainUrl.put("wap_domain", sceneDomainVo.getWapDomain());
+        domainUrl.put("wap_url", sceneDomainVo.getWapUrl());
+        domainUrl.put("web_url", sceneDomainVo.getWebUrl());
+        template.put("domain_url", domainUrl);
+
+        return template;
+    }
+
+    /**
+     * 页面初始化数据
+     *
+     * @param param@return
+     */
+    @Override
+    public NsDiyPageVo getPageInit(DiyPageInitParam param) {
+        JSONObject template = getTemplate(new TemplateParam());
+
+        NsDiyPageVo info = null;
+        if (param.getId() > 0) {
+            info = this.queryById(Long.valueOf(param.getId()));
+        } else if (!param.getName().isEmpty()) {
+            info = this.infoByName(param.getName());
+        }
+
+        if (!param.getName().isEmpty()) {
+            StartUpPageConfigVo startConfig = null;
+            for (String key : template.keySet()) {
+                if (ObjectUtil.defaultIfNull(template.getByPath(key + ".page", String.class), "").equals(startConfig.getPage())) {
+                    info = this.infoByName(key);
+                    if (info != null) {
+                        param.setType(key);
+                        param.setName(key);
+                    }
+                    break;
+                }
+            }
+        }
+
+        if (info != null) {
+            if (template.getJSONObject(info.getType()) != null) {
+                JSONObject page = template.getJSONObject(info.getType());
+                info.setTypeName(page.getStr("title"));
+                info.setPage(page.getStr("page"));
+            }
+        } else {
+            Long time = System.currentTimeMillis() / 1000;
+            String pageTitle = ObjectUtil.defaultIfBlank(param.getTitle(), "页面" + time);
+            String type = ObjectUtil.defaultIfBlank(param.getType(), "DIY_PAGE");
+            String name = type.equals("DIY_PAGE") ? "DIY_PAGE_RANDOM_" + time : type;
+            String typeName = "";
+            String templateName = "";
+            String pageRoute = "";
+            String mode = "diy";
+            Integer isDefault = 0;
+            String value = "";
+
+            JSONObject page = null;
+            if (template.getJSONObject(param.getName()) != null) {
+                page = template.getJSONObject(param.getName());
+                type = name = param.getName();
+                pageTitle = typeName = page.getStr("title");
+                pageRoute = page.getStr("page");
+                JSONObject pageData = this.getFirstPageData(type, "");
+//                if (pageData != null) {
+//                    mode = pageData.getByPath("template.mode", String.class);
+//                    value = pageData.getJSONObject("template").toString();
+//                    isDefault = 1;
+//                }
+
+                if (pageData != null) {
+                    mode = JSONPath.eval(pageData, "$.mode") + "";
+                    value = JSONPath.eval(pageData, "$.data") + "";
+                    isDefault = 1;
+                }
+            } else if (template.getJSONObject(param.getType()) != null) {
+                page = template.getJSONObject(param.getType());
+                typeName = page.getStr("title");
+                pageRoute = page.getStr("page");
+            }
+
+            info = new NsDiyPageVo();
+            info.setName(name);
+            info.setPageTitle(pageTitle);
+            info.setTitle(pageTitle);
+            info.setType(type);
+            info.setTypeName(typeName);
+            info.setTemplate(templateName);
+            info.setPage(pageRoute);
+            info.setMode(mode);
+            info.setValue(value);
+            info.setIsDefault(Long.valueOf(isDefault));
+        }
+
+        info.setComponent(getComponentList(info.getType()));
+
+        String wapDomain = "http://127.0.0.1:8080";
+
+        SceneDomainVo sceneDomainVo = new SceneDomainVo();
+        sceneDomainVo.setWapDomain(wapDomain);
+        sceneDomainVo.setWapUrl(wapDomain + "/wap");
+        sceneDomainVo.setWebUrl(wapDomain + "/web");
+        info.setDomainUrl(sceneDomainVo);
+
+        return info;
+    }
+
+    public JSONObject getComponentList(String type) {
+        String templateJsonStr = ResourceUtil.readUtf8Str("json/loader/diy/components.json");
+        JSONObject ComponentList = JSONUtil.parseObj(templateJsonStr);
+        JSONObject res = new JSONObject();
+        for (String formComponentObj : ComponentList.keySet()) {
+            JSONObject formComponent = ComponentList.getJSONObject(formComponentObj);
+            JSONObject list = formComponent.getJSONObject("list");
+            Iterator<Map.Entry<String, Object>> iterator = list.entrySet().iterator();
+            while (iterator.hasNext()) {
+                JSONObject cv = JSONUtil.parseObj(iterator.next().getValue());
+                if (cv.containsKey("support_page")) {
+                    JSONArray support = cv.getJSONArray("support_page");
+                    if (ObjectUtil.isNotEmpty(type)) {
+                        if (support != null && support.size() > 0 && !support.contains(type)) {
+                            iterator.remove();
+                            continue;
+                        }
+                    }
+                }
+                cv.remove("sort");
+                cv.remove("support_page");
+            }
+            // 根据 sort 排序
+            iterator = list.entrySet().iterator();
+            if(iterator.hasNext())
+            {
+                formComponent.put("list", sortJSONObjectBySortField(list));
+                res.put(formComponentObj, formComponent);
+            }
+        }
+        return res;
+    }
+
+    private JSONObject sortJSONObjectBySortField(JSONObject originalJsonObject) {
+        // 提取所有内部 JSONObject 到一个 List 中
+        List<Map.Entry<String, Object>> entryList = new ArrayList<>(originalJsonObject.entrySet());
+
+        // 对 List 进行排序
+        Collections.sort(entryList, new Comparator<Map.Entry<String, Object>>() {
+            public int compare(Map.Entry<String, Object> o1, Map.Entry<String, Object> o2) {
+                JSONObject jsonObj1 = (JSONObject) o1.getValue();
+                JSONObject jsonObj2 = (JSONObject) o2.getValue();
+                int sort1 = jsonObj1.getInt("sort");
+                int sort2 = jsonObj2.getInt("sort");
+                return Integer.compare(sort1, sort2);
+            }
+        });
+
+        // 创建一个新的 JSONObject 来存放排序后的结果
+        JSONObject sortedJsonObject = new JSONObject();
+        for (Map.Entry<String, Object> entry : entryList) {
+            sortedJsonObject.put(entry.getKey(), entry.getValue());
+        }
+
+        return sortedJsonObject;
+    }
+}

+ 255 - 0
ruoyi-modules/ruoyi-mall/src/main/java/org/dromara/mall/service/impl/NsDiyRouteServiceImpl.java

@@ -0,0 +1,255 @@
+package org.dromara.mall.service.impl;
+
+import cn.hutool.core.io.resource.ResourceUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.json.JSONArray;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.dromara.mall.domain.param.DiyRouteSearchParam;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyRouteBo;
+import org.dromara.mall.domain.vo.NsDiyRouteVo;
+import org.dromara.mall.domain.NsDiyRoute;
+import org.dromara.mall.mapper.NsDiyRouteMapper;
+import org.dromara.mall.service.INsDiyRouteService;
+
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 自定义路由Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyRouteServiceImpl  extends ServiceImpl<NsDiyRouteMapper, NsDiyRoute> implements INsDiyRouteService {
+
+    private final NsDiyRouteMapper baseMapper;
+
+    /**
+     * 查询自定义路由
+     *
+     * @param id 主键
+     * @return 自定义路由
+     */
+    @Override
+    public NsDiyRouteVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询自定义路由列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 自定义路由分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyRouteVo> queryPageList(NsDiyRouteBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyRoute> lqw = buildQueryWrapper(bo);
+        Page<NsDiyRouteVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的自定义路由列表
+     *
+     * @param bo 查询条件
+     * @return 自定义路由列表
+     */
+    @Override
+    public List<NsDiyRouteVo> queryList(NsDiyRouteBo bo) {
+        LambdaQueryWrapper<NsDiyRoute> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyRoute> buildQueryWrapper(NsDiyRouteBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyRoute> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyRoute::getId);
+        lqw.eq(bo.getSiteId() != null, NsDiyRoute::getSiteId, bo.getSiteId());
+        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), NsDiyRoute::getTitle, bo.getTitle());
+        lqw.like(StringUtils.isNotBlank(bo.getName()), NsDiyRoute::getName, bo.getName());
+        lqw.eq(StringUtils.isNotBlank(bo.getPage()), NsDiyRoute::getPage, bo.getPage());
+        lqw.eq(StringUtils.isNotBlank(bo.getShare()), NsDiyRoute::getShare, bo.getShare());
+        lqw.eq(bo.getIsShare() != null, NsDiyRoute::getIsShare, bo.getIsShare());
+        lqw.eq(bo.getSort() != null, NsDiyRoute::getSort, bo.getSort());
+        return lqw;
+    }
+
+    /**
+     * 新增自定义路由
+     *
+     * @param bo 自定义路由
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyRouteBo bo) {
+        NsDiyRoute add = MapstructUtils.convert(bo, NsDiyRoute.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改自定义路由
+     *
+     * @param bo 自定义路由
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyRouteBo bo) {
+        NsDiyRoute update = MapstructUtils.convert(bo, NsDiyRoute.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyRoute 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 searchParam 搜索参数
+     * @return PageResult<DiyRouteListedVo>
+     */
+    @Override
+    public List<NsDiyRouteVo> list(DiyRouteSearchParam searchParam) {
+        JSONObject linkEnum = getLink();
+        List<NsDiyRouteVo> diyRouteList = new LinkedList<>();
+        Long sort = 0L;
+
+        // 遍历第一层
+        for (String key : linkEnum.keySet()) {
+            JSONObject linkGroup = linkEnum.getJSONObject(key);
+
+            if (linkGroup.containsKey("child_list")) {
+                JSONArray childList = linkGroup.getJSONArray("child_list");
+
+                // 遍历第二层
+                for (int i = 0; i < childList.size(); i++) {
+                    JSONObject childItem = childList.getJSONObject(i);
+
+                    if (childItem.containsKey("child_list")) {
+                        JSONArray nestedChildList = childItem.getJSONArray("child_list");
+
+                        // 遍历第三层
+                        for (int j = 0; j < nestedChildList.size(); j++) {
+                            JSONObject nestedItem = nestedChildList.getJSONObject(j);
+
+                            // 应用过滤条件
+                            if (shouldAddItem(nestedItem, linkGroup, searchParam)) {
+                                NsDiyRouteVo vo = createDiyRouteVo(nestedItem, linkGroup, key, ++sort);
+                                diyRouteList.add(vo);
+                            }
+                        }
+                    } else if (ObjectUtil.isNotEmpty(childItem.getStr("url"))) {
+                        // 第二层直接有URL的项目
+                        if (shouldAddItem(childItem, linkGroup, searchParam)) {
+                            NsDiyRouteVo vo = createDiyRouteVo(childItem, linkGroup, key, ++sort);
+                            diyRouteList.add(vo);
+                        }
+                    }
+                }
+            }
+        }
+
+        return diyRouteList;
+    }
+
+    public static JSONObject getLink(){
+        //获取resource/json/loader/diy/links.json
+        String pageJsonStr = ResourceUtil.readUtf8Str("json/loader/diy/links.json");
+        JSONObject link = JSONUtil.parseObj(pageJsonStr);
+        return link;
+    }
+
+    /**
+     * 判断是否应该添加该项目
+     */
+    private boolean shouldAddItem(JSONObject item, JSONObject linkGroup, DiyRouteSearchParam searchParam) {
+        // title模糊匹配
+        if (ObjectUtil.isNotEmpty(searchParam.getTitle())) {
+            String itemTitle = item.getStr("title");
+            if (ObjectUtil.isEmpty(itemTitle) || !itemTitle.contains(searchParam.getTitle())) {
+                return false;
+            }
+        }
+
+        // url精确匹配
+        if (ObjectUtil.isNotEmpty(searchParam.getUrl())) {
+            String itemUrl = item.getStr("url");
+            if (!searchParam.getUrl().equals(itemUrl)) {
+                return false;
+            }
+        }
+
+        // addon_name匹配
+        if (ObjectUtil.isNotEmpty(searchParam.getAddonName())) {
+            JSONObject addonInfo = linkGroup.getJSONObject("addon_info");
+            if (addonInfo != null) {
+                String addonKey = addonInfo.getStr("key");
+                if (!searchParam.getAddonName().equals(addonKey)) {
+                    return false;
+                }
+            } else {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * 创建DiyRouteListVo对象
+     */
+    private NsDiyRouteVo createDiyRouteVo(JSONObject item, JSONObject linkGroup, String parentKey, Long sort) {
+        NsDiyRouteVo vo = new NsDiyRouteVo();
+        vo.setAddonInfo(ObjectUtil.defaultIfNull(linkGroup.getJSONObject("addon_info"), new JSONObject()));
+        vo.setTitle(item.getStr("title"));
+        vo.setName(item.getStr("name"));
+        vo.setParent(parentKey);
+        vo.setPage(item.getStr("url"));
+        vo.setIsShare(ObjectUtil.defaultIfNull(item.getLong("is_share"), 0L));
+        vo.setAction(ObjectUtil.defaultIfNull(item.getStr("action"), ""));
+        vo.setSort(sort);
+        return vo;
+    }
+}

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

@@ -0,0 +1,142 @@
+package org.dromara.mall.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import org.dromara.common.core.utils.MapstructUtils;
+import org.dromara.common.core.utils.StringUtils;
+import org.dromara.common.mybatis.core.page.TableDataInfo;
+import org.dromara.common.mybatis.core.page.PageQuery;
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.dromara.mall.domain.bo.NsDiyThemeBo;
+import org.dromara.mall.domain.vo.NsDiyThemeVo;
+import org.dromara.mall.domain.NsDiyTheme;
+import org.dromara.mall.mapper.NsDiyThemeMapper;
+import org.dromara.mall.service.INsDiyThemeService;
+
+import java.util.List;
+import java.util.Map;
+import java.util.Collection;
+
+/**
+ * 自定义主题配色Service业务层处理
+ *
+ * @author LionLi
+ * @date 2026-01-20
+ */
+@Slf4j
+@RequiredArgsConstructor
+@Service
+public class NsDiyThemeServiceImpl  extends ServiceImpl<NsDiyThemeMapper, NsDiyTheme> implements INsDiyThemeService {
+
+    private final NsDiyThemeMapper baseMapper;
+
+    /**
+     * 查询自定义主题配色
+     *
+     * @param id 主键
+     * @return 自定义主题配色
+     */
+    @Override
+    public NsDiyThemeVo queryById(Long id){
+        return baseMapper.selectVoById(id);
+    }
+
+    /**
+     * 分页查询自定义主题配色列表
+     *
+     * @param bo        查询条件
+     * @param pageQuery 分页参数
+     * @return 自定义主题配色分页列表
+     */
+    @Override
+    public TableDataInfo<NsDiyThemeVo> queryPageList(NsDiyThemeBo bo, PageQuery pageQuery) {
+        LambdaQueryWrapper<NsDiyTheme> lqw = buildQueryWrapper(bo);
+        Page<NsDiyThemeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
+        return TableDataInfo.build(result);
+    }
+
+    /**
+     * 查询符合条件的自定义主题配色列表
+     *
+     * @param bo 查询条件
+     * @return 自定义主题配色列表
+     */
+    @Override
+    public List<NsDiyThemeVo> queryList(NsDiyThemeBo bo) {
+        LambdaQueryWrapper<NsDiyTheme> lqw = buildQueryWrapper(bo);
+        return baseMapper.selectVoList(lqw);
+    }
+
+    private LambdaQueryWrapper<NsDiyTheme> buildQueryWrapper(NsDiyThemeBo bo) {
+        Map<String, Object> params = bo.getParams();
+        LambdaQueryWrapper<NsDiyTheme> lqw = Wrappers.lambdaQuery();
+        lqw.orderByAsc(NsDiyTheme::getId);
+        lqw.eq(bo.getSiteId() != null, NsDiyTheme::getSiteId, bo.getSiteId());
+        lqw.eq(StringUtils.isNotBlank(bo.getTitle()), NsDiyTheme::getTitle, bo.getTitle());
+        lqw.eq(StringUtils.isNotBlank(bo.getType()), NsDiyTheme::getType, bo.getType());
+        lqw.eq(StringUtils.isNotBlank(bo.getAddon()), NsDiyTheme::getAddon, bo.getAddon());
+        lqw.eq(StringUtils.isNotBlank(bo.getMode()), NsDiyTheme::getMode, bo.getMode());
+        lqw.eq(StringUtils.isNotBlank(bo.getThemeType()), NsDiyTheme::getThemeType, bo.getThemeType());
+        lqw.eq(StringUtils.isNotBlank(bo.getDefaultTheme()), NsDiyTheme::getDefaultTheme, bo.getDefaultTheme());
+        lqw.eq(StringUtils.isNotBlank(bo.getTheme()), NsDiyTheme::getTheme, bo.getTheme());
+        lqw.eq(StringUtils.isNotBlank(bo.getNewTheme()), NsDiyTheme::getNewTheme, bo.getNewTheme());
+        lqw.eq(bo.getIsSelected() != null, NsDiyTheme::getIsSelected, bo.getIsSelected());
+        return lqw;
+    }
+
+    /**
+     * 新增自定义主题配色
+     *
+     * @param bo 自定义主题配色
+     * @return 是否新增成功
+     */
+    @Override
+    public Boolean insertByBo(NsDiyThemeBo bo) {
+        NsDiyTheme add = MapstructUtils.convert(bo, NsDiyTheme.class);
+        validEntityBeforeSave(add);
+        boolean flag = baseMapper.insert(add) > 0;
+        if (flag) {
+            bo.setId(add.getId());
+        }
+        return flag;
+    }
+
+    /**
+     * 修改自定义主题配色
+     *
+     * @param bo 自定义主题配色
+     * @return 是否修改成功
+     */
+    @Override
+    public Boolean updateByBo(NsDiyThemeBo bo) {
+        NsDiyTheme update = MapstructUtils.convert(bo, NsDiyTheme.class);
+        validEntityBeforeSave(update);
+        return baseMapper.updateById(update) > 0;
+    }
+
+    /**
+     * 保存前的数据校验
+     */
+    private void validEntityBeforeSave(NsDiyTheme entity){
+        //TODO 做一些数据校验,如唯一约束
+    }
+
+    /**
+     * 校验并批量删除自定义主题配色信息
+     *
+     * @param ids     待删除的主键集合
+     * @param isValid 是否进行有效性校验
+     * @return 是否删除成功
+     */
+    @Override
+    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
+        if(isValid){
+            //TODO 做一些业务上的校验,判断是否需要校验
+        }
+        return baseMapper.deleteByIds(ids) > 0;
+    }
+}

+ 34 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/application.yml

@@ -0,0 +1,34 @@
+# Tomcat
+server:
+  port: 9216
+
+# Spring
+spring:
+  application:
+    # ????
+    name: ruoyi-mall
+  profiles:
+    # ????
+    active: @profiles.active@
+
+--- # nacos ??
+spring:
+  cloud:
+    nacos:
+      # nacos ????
+      server-addr: @nacos.server@
+      username: @nacos.username@
+      password: @nacos.password@
+      discovery:
+        # ???
+        group: @nacos.discovery.group@
+        namespace: ${spring.profiles.active}
+      config:
+        # ???
+        group: @nacos.config.group@
+        namespace: ${spring.profiles.active}
+  config:
+    import:
+      - optional:nacos:application-common.yml
+      - optional:nacos:datasource.yml
+      - optional:nacos:${spring.application.name}.yml

+ 101 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/account_change_type.json

@@ -0,0 +1,101 @@
+{
+  "point": {
+    "adjust": {
+      "name": "调整",
+      "inc": 1,
+      "dec": 1
+    },
+    "member_register": {
+      "name": "会员注册",
+      "inc": 1,
+      "dec": 0
+    },
+    "recharge_give": {
+      "name": "充值赠送",
+      "inc": 1,
+      "dec": 0
+    },
+    "level_upgrade": {
+      "name": "会员升级礼包",
+      "inc": 1,
+      "dec": 0
+    },
+    "day_sign_award": {
+      "name": "日签奖励",
+      "inc": 1,
+      "dec": 1
+    },
+    "continue_sign_award": {
+      "name": "连签奖励",
+      "inc": 1,
+      "dec": 0
+    }
+  },
+  "balance": {
+
+    "adjust": {
+      "name": "调整",
+      "inc": 1,
+      "dec": 1
+    },
+    "member_register": {
+      "name": "会员注册",
+      "inc": 1,
+      "dec": 0
+    },
+    "order": {
+      "name": "订单消费",
+      "inc": 0,
+      "dec": 1
+    },
+    "order_refund": {
+      "name": "订单退款",
+      "inc": 0,
+      "dec": 1
+    },
+    "recharge_refund": {
+      "name": "充值退款",
+      "inc": 0,
+      "dec": 1
+    },
+    "level_upgrade": {
+      "name": "会员升级礼包",
+      "inc": 1,
+      "dec": 0
+    },
+    "day_sign_award": {
+      "name": "日签奖励",
+      "inc": 1,
+      "dec": 1
+    },
+    "continue_sign_award": {
+      "name": "连签奖励",
+      "inc": 1,
+      "dec": 0
+    }
+  },
+  "money": {
+    "award": {
+      "name": "活动奖励",
+      "inc": 1,
+      "dec": 0
+    },
+    "cash_out": {
+      "name": "提现",
+      "inc": 0,
+      "dec": 1
+    }
+  },
+  "commission": {
+    "award": {
+      "name": "活动奖励",
+      "inc": 1,
+      "dec": 0
+    },
+    "cash_out": {
+      "name": "提现",
+      "inc": 0,
+      "dec": 1
+    }
+  }
+}

+ 10 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/account_type.json

@@ -0,0 +1,10 @@
+[
+  {
+    "name": "积分",
+    "key": "point"
+  },
+  {
+    "name": "余额",
+    "key": "balance"
+  }
+]

+ 47 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/app.json

@@ -0,0 +1,47 @@
+[
+  {
+    "name": "商家管理",
+    "key": "site_manage",
+    "group": "site",
+    "menu_key": "setting_system_basic_info",
+    "sort": 1,
+    "page": "/app/pages/site/setting",
+    "icon": "/addon/mall/site/menu/site_manage.png"
+  },
+  {
+    "name": "商家信息",
+    "key": "site_detail",
+    "group": "site",
+    "menu_key": "shop_setting_index",
+    "sort": 2,
+    "page": "/app/pages/site/info",
+    "icon": "/addon/mall/site/menu/site_detail.png"
+  },
+  {
+    "name": "客户管理",
+    "key": "member_manage",
+    "group": "member",
+    "menu_key": "shop_member_list",
+    "sort": 1,
+    "page": "/app/pages/member/index",
+    "icon": "/addon/mall/site/menu/member.png"
+  },
+  {
+    "name": "核销",
+    "key": "verify",
+    "group": "site",
+    "menu_key": "",
+    "sort": 3,
+    "page": "/app/pages/verify/index",
+    "icon": "/addon/mall/site/menu/verify.png"
+  },
+  {
+    "name": "核销记录",
+    "key": "verify_record",
+    "group": "site",
+    "menu_key": "",
+    "sort": 4,
+    "page": "/app/pages/verify/record",
+    "icon": "/addon/mall/site/menu/verify_record.png"
+  }
+]

+ 17 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/app_group.json

@@ -0,0 +1,17 @@
+[
+  {
+    "name": "客户",
+    "key": "member",
+    "sort": 2
+  },
+  {
+    "name": "配送",
+    "key": "delivery",
+    "sort": 4
+  },
+  {
+    "name": "商家",
+    "key": "site",
+    "sort": 5
+  }
+]

+ 20 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/app_user.json

@@ -0,0 +1,20 @@
+[
+  {
+    "name": "商家信息",
+    "key": "site_detail",
+    "group": "site",
+    "menu_key": "shop_setting_index",
+    "sort": 2,
+    "page": "/app/pages/site/info",
+    "icon": "/addon/mall/site/menu/site_detail.png"
+  },
+  {
+    "name": "客户管理",
+    "key": "member_manage",
+    "group": "member",
+    "menu_key": "shop_member_list",
+    "sort": 1,
+    "page": "/app/pages/member/index",
+    "icon": "/addon/mall/site/menu/member.png"
+  }
+]

+ 26 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/bottom_nav.json

@@ -0,0 +1,26 @@
+[
+  {
+    "iconPath": "addon/mall/site/tabbar/home.png",
+    "iconSelectPath": "addon/mall/site/tabbar/home-selected.png",
+    "text": "工作台",
+    "link":{
+      "url":"/app/pages/index/index"
+    }
+  },
+  {
+    "iconPath": "addon/mall/site/tabbar/menu.png",
+    "iconSelectPath": "addon/mall/site/tabbar/menu-selected.png",
+    "text": "应用",
+    "link":{
+      "url":"/app/pages/index/menu"
+    }
+  },
+  {
+    "iconPath": "addon/mall/site/tabbar/my.png",
+    "iconSelectPath": "addon/mall/site/tabbar/my-selected.png",
+    "text": "我的",
+    "link":{
+      "url":"/app/pages/site/index"
+    }
+  }
+]

+ 3 - 0
ruoyi-modules/ruoyi-mall/src/main/resources/json/loader/adminapp/stat.json

@@ -0,0 +1,3 @@
+[
+
+]

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików