From ed277ece348dae9bc6e36c0fc9f69ae8a3825912 Mon Sep 17 00:00:00 2001
From: lige <bestlige@outlook.com>
Date: 星期四, 18 四月 2024 17:57:55 +0800
Subject: [PATCH] 填鸭表单

---
 ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormItemRequest.java                 |   25 
 ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormRequest.java                     |   53 
 ltkj-system/src/main/java/com/ltkj/tduck/struct/FormSettingSchemaStruct.java               |   78 
 ltkj-system/src/main/java/com/ltkj/tduck/handler/JacksonTypeHandler.java                   |   64 
 ltkj-system/src/main/java/com/ltkj/tduck/handler/LongToStringSerializer.java               |   34 
 ltkj-system/src/main/java/com/ltkj/tduck/vo/FormDataTableVO.java                           |   26 
 ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyOptions.java                          |   32 
 ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataMysqlService.java            |  139 +
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormLogicEntity.java                   |   88 
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormItemService.java                  |   60 
 ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormSettingController.java                 |  143 +
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormLogicService.java                 |    7 
 ltkj-admin/src/main/resources/config/ehcache.xml                                           |   57 
 ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyTemplateController.java    |  137 +
 ltkj-system/src/main/java/com/ltkj/tduck/service/FormTemplateCategoryService.java          |   14 
 ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyTemplateServiceImpl.java        |   16 
 ltkj-system/src/main/java/com/ltkj/tduck/struct/FormDataFilterStruct.java                  |  118 +
 ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTempQues.java                         |   33 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/FormTemplateCategoryEntity.java            |   26 
 ltkj-admin/src/main/java/com/ltkj/web/tduck/WxJsApiController.java                         |   74 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormSettingServiceImpl.java      |  194 +
 ltkj-system/src/main/java/com/ltkj/tduck/enums/FormSourceTypeEnum.java                     |   30 
 ltkj-system/src/main/java/com/ltkj/tduck/constant/FormSettingConstants.java                |   21 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/FormTypeEnum.java                           |   38 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/FormLogicConditionExpressionEnum.java       |   28 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormThemeMapper.java                       |   14 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/IDictEnum.java                              |   43 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/FormThemeEntity.java                       |   44 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/SortUtils.java                              |  109 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/LongToStringSerializer.java                 |   34 
 ltkj-system/src/main/java/com/ltkj/tduck/request/CheckWritePwdRequest.java                 |   14 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormItemServiceImpl.java         |  105 
 ltkj-system/src/main/java/com/ltkj/tduck/constant/CommonConstants.java                     |   96 
 ltkj-system/src/main/java/com/ltkj/tduck/vo/OperateFormItemVO.java                         |   37 
 ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyTemplateService.java                |    5 
 ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyQuestionMapper.xml                        |  275 ++
 ltkj-system/src/main/java/com/ltkj/tduck/constant/FormRedisKeyConstants.java               |   66 
 ltkj-admin/src/main/resources/application.yml                                              |    4 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormItemMapper.java                    |   14 
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormSettingService.java               |   61 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/CacheUtils.java                             |  133 +
 ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyRecord.java                           |   76 
 ltkj-common/src/main/java/com/ltkj/common/utils/http/HttpUtils.java                        |   44 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/EsTypeEnum.java                             |   32 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormThemeServiceImpl.java            |   46 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/FormItemTypeEnum.java                       |   60 
 ltkj-system/src/main/java/com/ltkj/tduck/struct/WriteSettingSchemaStruct.java              |  239 ++
 ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyTemplateMapper.xml                        |  325 +-
 ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormTemplateTypeRequest.java         |   18 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/ValidatorUtils.java                         |   57 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormSettingEntity.java                 |   36 
 ltkj-system/src/main/java/com/ltkj/tduck/handler/AutoFillMetaInfoHandler.java              |   30 
 ltkj-system/src/main/java/com/ltkj/tduck/struct/OptionQuotaListStruct.java                 |   52 
 ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataBaseService.java             |  135 +
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormTemplateCategoryServiceImpl.java |   18 
 ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyQuestion.java                         |   58 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/Result.java                                 |   89 
 ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormResultRequest.java               |   60 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormLogicServiceImpl.java        |   14 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormItemEntity.java                    |  145 +
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormViewCountEntity.java               |   36 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormTemplateCategoryMapper.java            |   14 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormDataMapper.java                    |   54 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/TBaseEntity.java                           |   57 
 ltkj-common/pom.xml                                                                        |   21 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/PageRequest.java                           |   21 
 ltkj-system/src/main/java/com/ltkj/tduck/struct/InputResultStruct.java                     |   29 
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormViewCountService.java             |   27 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/FormStatusEnum.java                         |   31 
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormDataService.java                  |   69 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormServiceImpl.java             |   29 
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormThemeService.java                 |   21 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormThemeServiceImpl.java        |   27 
 ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTemplate.java                         |   42 
 ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyQuestionServiceImpl.java        |   52 
 ltkj-system/src/main/java/com/ltkj/tduck/vo/UserFormDetailVO.java                          |   62 
 ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyTemplateMapper.java                   |    5 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormThemeEntity.java                   |   86 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormViewCountServiceImpl.java    |   29 
 ltkj-system/src/main/java/com/ltkj/tduck/request/SortFormItemRequest.java                  |   28 
 ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormDataServiceImpl.java         |  159 +
 ltkj-system/src/main/java/com/ltkj/tduck/utils/JsonUtils.java                              |  276 ++
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormViewCountMapper.java               |   24 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormEntity.java                        |  104 
 ltkj-system/src/main/java/com/ltkj/tduck/vo/FormFieldVO.java                               |   64 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/ShortIdUtils.java                           |   41 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormMapper.java                        |   12 
 ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyQuestionService.java                |   19 
 ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormController.java                        |  311 ++
 ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyQuestionMapper.java                   |   80 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/TimeRangeEnum.java                          |   57 
 ltkj-system/src/main/java/com/ltkj/tduck/service/FormThemeService.java                     |   56 
 ltkj-system/src/main/java/com/ltkj/tduck/constant/ResponseCodeConstants.java               |   45 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/HtmlUtils.java                              |   20 
 ltkj-system/src/main/java/com/ltkj/tduck/struct/CheckboxSchemaStruct.java                  |   37 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormSettingMapper.java                 |   14 
 ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormResultController.java                  |  254 ++
 ltkj-system/src/main/java/com/ltkj/tduck/domain/SysBaseEntity.java                         |   50 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormLogicMapper.java                   |   15 
 ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormThemeMapper.java                   |   14 
 ltkj-system/src/main/java/com/ltkj/tduck/utils/FormDataUtils.java                          |  144 +
 ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyQuestionController.java    |    4 
 ltkj-system/src/main/java/com/ltkj/tduck/constant/FormConstants.java                       |   35 
 ltkj-system/src/main/java/com/ltkj/tduck/handler/BooleanTypeHandler.java                   |   47 
 ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormDataEntity.java                    |  112 
 ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormService.java                      |   24 
 ltkj-system/src/main/java/com/ltkj/tduck/enums/FormPermsBtnTypeEnum.java                   |   25 
 107 files changed, 6,461 insertions(+), 445 deletions(-)

diff --git a/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyQuestionController.java b/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyQuestionController.java
index 8dc16bf..1d0bdf5 100644
--- a/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyQuestionController.java
+++ b/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyQuestionController.java
@@ -62,7 +62,7 @@
      */
     //@PreAuthorize("@ss.hasPermi('hosp:question:query')")
     @GetMapping(value = "/{qid}")
-    public AjaxResult getInfo(@PathVariable("qid") Long qid) {
+    public AjaxResult getInfo(@PathVariable("qid") String qid) {
         return success(tjSurveyQuestionService.selectTjSurveyQuestionByQid(qid));
     }
 
@@ -92,7 +92,7 @@
     //@PreAuthorize("@ss.hasPermi('hosp:question:remove')")
     @Log(title = "闂嵎闂", businessType = BusinessType.DELETE)
     @DeleteMapping("/{qids}")
-    public AjaxResult remove(@PathVariable Long[] qids) {
+    public AjaxResult remove(@PathVariable String[] qids) {
         return toAjax(tjSurveyQuestionService.deleteTjSurveyQuestionByQids(qids));
     }
 }
diff --git a/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyTemplateController.java b/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyTemplateController.java
index bb4197a..36f2de7 100644
--- a/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyTemplateController.java
+++ b/ltkj-admin/src/main/java/com/ltkj/web/controller/system/TjSurveyTemplateController.java
@@ -6,11 +6,18 @@
 import java.util.Map;
 import javax.servlet.http.HttpServletResponse;
 
+import cn.hutool.core.date.DateTime;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.ltkj.hosp.domain.TjSurveyOptions;
 import com.ltkj.hosp.domain.TjSurveyQuestion;
 import com.ltkj.hosp.domain.TjSurveyTempQues;
 import com.ltkj.hosp.service.ITjSurveyQuestionService;
+import com.ltkj.system.service.ISysConfigService;
+import com.ltkj.tduck.domain.UserFormEntity;
+import com.ltkj.tduck.enums.FormSourceTypeEnum;
+import com.ltkj.tduck.enums.FormStatusEnum;
+import com.ltkj.tduck.service.UserFormService;
+import com.ltkj.tduck.utils.ShortIdUtils;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
 import org.springframework.security.access.prepost.PreAuthorize;
@@ -40,6 +47,37 @@
 
     @Autowired
     private ITjSurveyQuestionService tjSurveyQuestionService;
+    @Autowired
+    private ISysConfigService configService;
+
+    @Autowired
+    private UserFormService formService;
+
+
+    /**
+     * 鍒ゆ柇鏄惁寮�鍚~楦〃鍗曡璁�
+     */
+    @ApiOperation(value = "鍒ゆ柇鏄惁寮�鍚~楦〃鍗曡璁�")
+    @GetMapping(value = "/needDesign")
+    public AjaxResult needDesign() {
+        final String call = configService.selectConfigByKey("need_design");
+        return AjaxResult.success(call);
+    }
+
+    /**
+     * 鍒ゆ柇璇ユā鏉挎槸鍚﹀彲鍒犻櫎
+     */
+    @ApiOperation(value = "鍒ゆ柇璇ユā鏉挎槸鍚﹀彲鍒犻櫎")
+    @GetMapping(value = "/canDelete")
+    public AjaxResult canDelete(Long id) {
+//        List<FwdPlanInfoVo> fwdPlanInfoVos = fwdSqlMapper.canDelete(id);
+//        if (fwdPlanInfoVos!=null && fwdPlanInfoVos.size()>0){
+//            return AjaxResult.success(false);
+//        }
+        return AjaxResult.success(false);
+    }
+
+
 
     /**
      * 鏌ヨ闂嵎妯℃澘鍒楄〃
@@ -73,26 +111,52 @@
         return success(tjSurveyTemplateService.selectTjSurveyTemplateByMid(mid));
     }
 
-    /**
-     * 鑾峰彇闂嵎妯℃澘
-     */
+//    /**
+//     * 鑾峰彇闂嵎妯℃澘
+//     */
+//    @GetMapping("/getQuesByMid")
+//    @ApiOperation(value = "鑾峰彇闂嵎妯℃澘淇℃伅")
+//    public AjaxResult getQuesByMid(@RequestParam Long mid) {
+//        List<TjSurveyQuestion> l1=new ArrayList<>();
+//        TjSurveyTemplate byId = tjSurveyTemplateService.selectTjSurveyTemplateByMid(mid);
+//        List<TjSurveyTempQues> tjSurveyTempQuesList = byId.getTjSurveyTempQuesList();
+//        if (tjSurveyTempQuesList!=null){
+//            for (TjSurveyTempQues tjSurveyTempQues : tjSurveyTempQuesList) {
+//                TjSurveyQuestion byId1 = tjSurveyQuestionService.selectTjSurveyQuestionByQid(tjSurveyTempQues.getQid());
+//                if (byId1!=null){
+//                    l1.add(byId1);
+//                }
+//            }
+//            return AjaxResult.success(l1);
+//        }
+//        return AjaxResult.success("鏆傛棤淇℃伅");
+//    }
+
     @GetMapping("/getQuesByMid")
     @ApiOperation(value = "鑾峰彇闂嵎妯℃澘淇℃伅")
     public AjaxResult getQuesByMid(@RequestParam Long mid) {
-        List<TjSurveyQuestion> l1=new ArrayList<>();
-        TjSurveyTemplate byId = tjSurveyTemplateService.selectTjSurveyTemplateByMid(mid);
-        List<TjSurveyTempQues> tjSurveyTempQuesList = byId.getTjSurveyTempQuesList();
-        if (tjSurveyTempQuesList!=null){
-            for (TjSurveyTempQues tjSurveyTempQues : tjSurveyTempQuesList) {
-                TjSurveyQuestion byId1 = tjSurveyQuestionService.selectTjSurveyQuestionByQid(tjSurveyTempQues.getQid());
-                if (byId1!=null){
-                    l1.add(byId1);
-                }
+        TjSurveyTemplate byId = tjSurveyTemplateService.selectTemplateByMid1(Long.valueOf(mid));
+        if(null !=byId){
+            if ("1".equals(byId.getQybz())){
+                return AjaxResult.success("璇ラ棶鍗锋ā鏉夸笉瀛樺湪鎴栧凡鍋滅敤");
             }
-            return AjaxResult.success(l1);
+            //鍒ゆ柇鏄惁鏈夐棶棰�
+            if(byId.getDesignId()!=null){
+                return AjaxResult.success(byId.getDesignId());
+            }
+            LambdaQueryWrapper<TjSurveyQuestion> wq1=new LambdaQueryWrapper<>();
+            wq1.eq(TjSurveyQuestion::getMid,byId.getMid());
+            final List<TjSurveyQuestion> list1 = tjSurveyQuestionService.list(wq1);
+            for (TjSurveyQuestion tjSurveyQuestion : list1) {
+                final List<TjSurveyOptions> tjSurveyOptions = tjSurveyQuestionService.selectOptionsByQid(tjSurveyQuestion.getQid());
+                tjSurveyQuestion.setTjSurveyOptionsList(tjSurveyOptions);
+            }
+            return AjaxResult.success(list1);
+
         }
         return AjaxResult.success("鏆傛棤淇℃伅");
     }
+
 
     /**
      * 鏂板闂嵎妯℃澘
@@ -101,7 +165,33 @@
     @Log(title = "闂嵎妯℃澘", businessType = BusinessType.INSERT)
     @PostMapping
     public AjaxResult add(@RequestBody TjSurveyTemplate tjSurveyTemplate) {
-        return toAjax(tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate));
+//        return toAjax(tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate));
+        final String call = configService.selectConfigByKey("need_design");
+        //鍒ゆ柇鏄惁寮�鍚~楦〃鍗曡璁�
+        if ("true".equals(call)){
+            UserFormEntity form=new UserFormEntity();
+            form.setFormKey(ShortIdUtils.genId());
+            form.setName("<h2 style=\"text-align: center;\">"+tjSurveyTemplate.getTempName()+"</h2>");
+            form.setStatus(1);
+            form.setSourceType(1);
+            form.setCreateTime(new DateTime());
+            form.setType("1");
+            form.setDeleted(false);
+            final boolean save = formService.save(form);
+            if (save){
+                tjSurveyTemplate.setDesignId(form.getFormKey());
+                final int i = tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate);
+                if (i==1) {
+                    return AjaxResult.success(form);
+                }
+            }
+        }else{
+            final int i = tjSurveyTemplateService.insertTjSurveyTemplate(tjSurveyTemplate);
+            if (i==1) {
+                return AjaxResult.success(false);
+            }
+        }
+        return AjaxResult.success(false);
     }
 
     /**
@@ -123,4 +213,23 @@
     public AjaxResult remove(@PathVariable Long[] mids) {
         return toAjax(tjSurveyTemplateService.deleteTjSurveyTemplateByMids(mids));
     }
+
+
+    /**
+     * 闂嵎鍚敤绂佺敤
+     */
+    @GetMapping("/updateQybz")
+    @ApiOperation(value = "闂嵎鍚敤绂佺敤")
+    public AjaxResult updateQybz(@RequestParam Long mid,@RequestParam String qybz) {
+        final TjSurveyTemplate byId = tjSurveyTemplateService.selectTemplateByMid1(mid);
+        byId.setQybz(qybz);
+        if ("0".equals(qybz) && tjSurveyTemplateService.qybzTjSurveyTemplateByQy(byId.getMid())==1){
+            return AjaxResult.success("鍚敤鎴愬姛锛�");
+        }else if ("1".equals(qybz) && tjSurveyTemplateService.qybzTjSurveyTemplateByJy(byId.getMid())==1){
+            return AjaxResult.success("绂佺敤鎴愬姛锛�");
+        }else {
+            return AjaxResult.error("鍑洪敊浜嗭紝璇疯仈绯诲伐浣滀汉鍛橈紒");
+        }
+
+    }
 }
diff --git a/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormController.java b/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormController.java
new file mode 100644
index 0000000..18487d7
--- /dev/null
+++ b/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormController.java
@@ -0,0 +1,311 @@
+package com.ltkj.web.tduck;
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.json.JSONObject;
+import cn.hutool.json.JSONUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ltkj.common.core.domain.AjaxResult;
+import com.ltkj.tduck.constant.CommonConstants;
+import com.ltkj.tduck.domain.*;
+import com.ltkj.tduck.enums.FormStatusEnum;
+import com.ltkj.tduck.enums.FormTypeEnum;
+import com.ltkj.tduck.request.QueryFormItemRequest;
+import com.ltkj.tduck.request.QueryFormRequest;
+import com.ltkj.tduck.request.QueryFormTemplateTypeRequest;
+import com.ltkj.tduck.request.SortFormItemRequest;
+import com.ltkj.tduck.service.*;
+import com.ltkj.tduck.utils.FormDataUtils;
+import com.ltkj.tduck.utils.Result;
+import com.ltkj.tduck.utils.SortUtils;
+import com.ltkj.tduck.utils.ValidatorUtils;
+import com.ltkj.tduck.vo.FormFieldVO;
+import com.ltkj.tduck.vo.OperateFormItemVO;
+import com.ltkj.tduck.vo.UserFormDetailVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import javax.annotation.security.PermitAll;
+import javax.validation.constraints.NotBlank;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.List;
+
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟
+ **/
+@RequiredArgsConstructor
+@RestController
+@Slf4j
+//@RequestMapping("/tduck-api")
+public class UserFormController {
+    @Resource
+    private final UserFormService formService;
+    @Resource
+    private final UserFormItemService formItemService;
+    @Resource
+    private final FormTemplateCategoryService formTemplateCategoryService;
+    @Resource
+    private final SortUtils sortUtils;
+
+    private final UserFormThemeService userFormThemeService;
+    private final UserFormLogicService userFormLogicService;
+
+
+    /**
+     * 鏌ヨ琛ㄥ崟
+     */
+    @GetMapping("/user/form/{key}")
+    public AjaxResult queryFormByKey(@PathVariable @NotBlank String key) {
+        return AjaxResult.success(formService.getByKey(key));
+    }
+
+    /**
+     * 椤圭洰琛ㄥ崟椤规煡璇�
+     */
+    @GetMapping("/user/form/item/list")
+    public AjaxResult queryFormItems(QueryFormItemRequest request) {
+        ValidatorUtils.validateEntity(request);
+//        FormAuthUtils.hasPermission(request.getKey());
+        List<UserFormItemEntity> itemEntityList = formItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getKey()).eq(ObjectUtil.isNotNull(request.getDisplayType()), UserFormItemEntity::getDisplayType, request.getDisplayType()));
+        itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort));
+        return AjaxResult.success(itemEntityList);
+    }
+
+
+    /**
+     * 鍒嗛〉鏌ヨ椤圭洰鍒嗙被
+     *
+     * @return
+     */
+    @GetMapping("/form/template/type/list")
+    public AjaxResult queryFormTemplateTypes(QueryFormTemplateTypeRequest.List request) {
+        return AjaxResult.success(formTemplateCategoryService.list(Wrappers.<FormTemplateCategoryEntity>lambdaQuery()
+                .orderByDesc(FormTemplateCategoryEntity::getSort)));
+    }
+
+
+    /**
+     * 琛ㄥ崟鏇存柊
+     *
+     * @param form
+     */
+    @PostMapping("/user/form/update")
+    public AjaxResult updateForm(@RequestBody UserFormEntity form) {
+//        ValidatorUtils.validateEntity(form, AddGroup.class);
+        UserFormEntity oldForm = formService.getByKey(form.getFormKey());
+        if (ObjectUtil.isNotNull(oldForm)) {
+            form.setId(oldForm.getId());
+            formService.updateById(form);
+        }
+        return AjaxResult.success();
+    }
+
+
+    /**
+     * 椤圭洰琛ㄥ崟椤瑰垱寤�
+     *
+     * @param entity
+     */
+    @PostMapping("/user/form/item/create")
+    public AjaxResult createFormItem(@RequestBody UserFormItemEntity entity) {
+//        ValidatorUtils.validateEntity(entity, AddGroup.class);
+        if (ObjectUtil.isNull(entity.getDisplayType())) {
+            entity.setDisplayType(false);
+        }
+        if (ObjectUtil.isNull(entity.getHideType())) {
+            entity.setHideType(false);
+        }
+        //鎺掑簭涓嬫爣璁$畻
+        entity.setSort(sortUtils.getInitialSortPosition(entity.getFormKey()));
+        entity.setSpecialType(formItemService.isSpecialTypeItem(entity));
+        entity.setCreateTime(new Date());
+        boolean save = formItemService.save(entity);
+        return AjaxResult.success(new OperateFormItemVO(entity.getSort(), entity.getId(), save, false));
+    }
+
+
+    /**
+     * 鎵归噺椤圭洰琛ㄥ崟椤瑰垱寤�
+     */
+    @PostMapping("/user/form/item/batch/create")
+    public AjaxResult batchCreateFormItem(@RequestBody List<UserFormItemEntity> itemEntityList) {
+        //鎺掑簭涓嬫爣璁$畻
+        itemEntityList.forEach(item -> item.setSort(sortUtils.getInitialSortPosition(item.getFormKey())));
+        itemEntityList.forEach(item -> item.setDisplayType(false));
+        itemEntityList.forEach(item -> item.setHideType(false));
+        itemEntityList.forEach(item -> item.setSpecialType(false));
+        boolean save = formItemService.saveBatch(itemEntityList);
+        AjaxResult ajaxResult = new AjaxResult();
+        ajaxResult.put("code", 200);
+        ajaxResult.put("data", null);
+        ajaxResult.put("msg", null);
+        return ajaxResult;
+    }
+
+
+    /**
+     * 琛ㄥ崟椤瑰垹闄�
+     */
+    @PostMapping("/user/form/item/delete")
+    public AjaxResult deleteFormItem(@RequestBody UserFormItemEntity request) {
+//        FormAuthUtils.hasPermission(request.getFormKey());
+        boolean delete = formItemService.remove(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).eq(UserFormItemEntity::getFormItemId, request.getFormItemId()));
+        return AjaxResult.success(delete);
+    }
+
+
+    /**
+     * 琛ㄥ崟椤规洿鏂�
+     *
+     * @param request
+     */
+    @PostMapping("/user/form/item/update")
+    public AjaxResult updateFormItem(@RequestBody UserFormItemEntity request) {
+//        FormAuthUtils.hasPermission(request.getFormKey());
+//        ValidatorUtils.validateEntity(request, UpdateGroup.class);
+        request.setSpecialType(formItemService.isSpecialTypeItem(request));
+        boolean update = formItemService.update(request, Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).eq(UserFormItemEntity::getFormItemId, request.getFormItemId()));
+        return AjaxResult.success(update);
+    }
+
+    /**
+     * 琛ㄥ崟椤规帓搴�
+     *
+     * @param request
+     */
+    @PostMapping("/user/form/item/sort")
+    public AjaxResult sortFormItem(@RequestBody SortFormItemRequest request) {
+//        ValidatorUtils.validateEntity(request);
+        if (ObjectUtil.isNull(request.getAfterPosition()) && ObjectUtil.isNull(request.getBeforePosition())) {
+            return AjaxResult.success();
+        }
+        UserFormItemEntity itemEntity = formItemService.getOne(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).eq(UserFormItemEntity::getFormItemId, request.getFormItemId()));
+        Long sort = sortUtils.calcSortPosition(request.getBeforePosition(), request.getAfterPosition(), request.getFormKey());
+        if (sortUtils.sortAllList(request.getBeforePosition(), request.getAfterPosition(), request.getFormKey(), sort)) {
+            return AjaxResult.success(new OperateFormItemVO(itemEntity.getSort(), itemEntity.getId(), true, true));
+        }
+        itemEntity.setSort(sort);
+        boolean b = formItemService.updateById(itemEntity);
+        return AjaxResult.success(new OperateFormItemVO(itemEntity.getSort(), itemEntity.getId(), b, false));
+    }
+
+
+    /**
+     * 鏌ヨ琛ㄥ崟璇︽儏
+     * 鍖呭惈琛ㄥ崟淇℃伅 琛ㄥ崟瀛楁淇℃伅 琛ㄥ崟涓婚
+     *
+     * @param key
+     */
+    @GetMapping("/user/form/details/{key}")
+    @PermitAll
+    public AjaxResult queryFormDetails(@PathVariable @NotBlank String key) {
+        UserFormEntity form = formService.getByKey(key);
+        if (ObjectUtil.isNull(form)) {
+            return AjaxResult.success();
+        }
+        List<UserFormItemEntity> formItemList = formItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().ne(UserFormItemEntity::getHideType, 1).eq(UserFormItemEntity::getFormKey, key));
+        formItemList.sort(Comparator.comparing(UserFormItemEntity::getSort));
+        UserFormThemeEntity theme = userFormThemeService.getByKey(key);
+        UserFormLogicEntity formLogic = userFormLogicService.getOne(Wrappers.<UserFormLogicEntity>lambdaQuery().eq(UserFormLogicEntity::getFormKey, key));
+        // 濡傛灉鏄�冭瘯 绉婚櫎姝g‘绛旀 閬垮厤鎶婃纭瓟妗堣繑鍥炲埌鍓嶇
+        if (form.getType() == FormTypeEnum.EXAM.getValue().toString()) {
+            formItemList.forEach(item -> {
+                JSONObject schemeJson = JSONUtil.parseObj(item.getScheme());
+                if (schemeJson.containsKey("examConfig")) {
+                    schemeJson.getJSONObject("examConfig").remove("answer");
+                }
+                item.setScheme(schemeJson);
+            });
+        }
+        return AjaxResult.success(new UserFormDetailVO(new UserFormDetailVO.UserForm(form), formItemList, theme, formLogic));
+    }
+
+
+    /**
+     * 鍙戝竷琛ㄥ崟
+     */
+    @PostMapping("/user/form/publish")
+    public AjaxResult publishForm(@RequestBody UserFormEntity request) {
+//        FormAuthUtils.hasPermission(request.getFormKey());
+        long count = formItemService.count(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()));
+        if (count == CommonConstants.ConstantNumber.ZERO) {
+            return AjaxResult.error("鏃犳湁鏁堣〃鍗曢」锛屾棤娉曞彂甯�");
+        }
+        UserFormEntity entity = formService.getByKey(request.getFormKey());
+        entity.setStatus(2);
+        return AjaxResult.success(formService.updateById(entity));
+    }
+
+
+    /**
+     * 鍋滄鏀堕泦
+     *
+     * @param request
+     */
+    @PostMapping("/user/form/stop")
+    public Result stopForm(@RequestBody UserFormEntity request) {
+//        FormAuthUtils.hasPermission(request.getFormKey());
+        UserFormEntity entity = formService.getByKey(request.getFormKey());
+        entity.setStatus(3);
+        return Result.success(formService.updateById(entity));
+    }
+
+
+    /**
+     * 鏌ヨ鎴戠殑琛ㄥ崟鍒嗛〉
+     */
+    @GetMapping("/user/form/page")
+    public Result queryMyForms(@RequestAttribute Long userId, QueryFormRequest.Page request) {
+        LambdaQueryWrapper<UserFormEntity> queryWrapper = Wrappers.<UserFormEntity>lambdaQuery().eq(UserFormEntity::getUserId, userId)
+                .eq(ObjectUtil.isNotNull(request.getFolder()), UserFormEntity::getFolder, request.getFolder())
+                .eq(ObjectUtil.isNotNull(request.getType()), UserFormEntity::getType, request.getType())
+                .eq(UserFormEntity::getDeleted, 0).func(i -> {
+                    // 閫氳繃鏂囦欢鍚嶆悳绱㈡椂 鍙互鎼滅储鍒板瓙鏂囦欢澶逛笅鐨勮〃鍗�
+                    if (StrUtil.isNotBlank(request.getName()) && request.getFolderId() == 0) {
+                    } else {
+                        i.eq(UserFormEntity::getFolderId, request.getFolderId());
+                    }
+                }).eq(ObjectUtil.isNotNull(request.getStatus()), UserFormEntity::getStatus, request.getStatus()).like(StrUtil.isNotBlank(request.getName()),
+                        UserFormEntity::getName, request.getName()).le(ObjectUtil.isNotNull(request.getEndDateTime()), UserFormEntity::getUpdateTime,
+                        request.getEndDateTime()).ge(ObjectUtil.isNotNull(request.getBeginDateTime()), UserFormEntity::getUpdateTime,
+                        request.getBeginDateTime()).orderByDesc(UserFormEntity::getFolder)
+//                .orderByDesc(TBaseEntity::getCreateTime)
+                ;
+        return Result.success(formService.page(request.toMybatisPage(), queryWrapper));
+    }
+
+
+    /**
+     * 鑾峰彇琛ㄥ崟瀛楁 鍖呮嫭绯荤粺榛樿瀛楁
+     */
+    @GetMapping("/user/form/fields/{formKey}")
+    public Result queryUserFormFields(@PathVariable String formKey) {
+        return Result.success(formItemService.listAllFormFields(formKey));
+    }
+
+    /**
+     * 鑾峰彇琛ㄥ崟鍥哄畾瀛楁
+     * 鎵�鏈夎〃鍗曢兘鍖呭惈 鐢ㄤ簬鏌ョ湅璇︽儏鍙充晶鏄剧ず
+     */
+    @GetMapping("/user/form/fixed/fields/{formKey}")
+    public Result queryUserFormFixedFields(@PathVariable String formKey) {
+        // 鏌ヨ琛ㄥ崟绫诲瀷
+        UserFormEntity userFormEntity = formService.getByKey(formKey);
+        List<FormFieldVO> fields = new ArrayList<>();
+        FormDataUtils.addFormBaseDataField(fields);
+        fields.add(new FormFieldVO("submitUaOs", "鎿嶄綔绯荤粺"));
+        fields.add(new FormFieldVO("submitUaDevice", "璁惧"));
+        fields.add(new FormFieldVO(UserFormDataEntity.Fields.submitBrowser, "娴忚鍣�"));
+        fields.add(new FormFieldVO(UserFormDataEntity.Fields.submitAddress, "鍦板潃"));
+        fields.add(new FormFieldVO(UserFormDataEntity.Fields.submitRequestIp, "IP"));
+        fields.add(new FormFieldVO(UserFormDataEntity.Fields.wxUserInfo, "寰俊鐢ㄦ埛"));
+        return Result.success(fields);
+    }
+
+}
diff --git a/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormResultController.java b/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormResultController.java
new file mode 100644
index 0000000..7f1fca1
--- /dev/null
+++ b/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormResultController.java
@@ -0,0 +1,254 @@
+package com.ltkj.web.tduck;
+
+import cn.hutool.core.date.DateUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.ltkj.common.core.domain.AjaxResult;
+import com.ltkj.common.utils.SecurityUtils;
+import com.ltkj.common.utils.http.HttpUtils;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import com.ltkj.tduck.domain.UserFormViewCountEntity;
+import com.ltkj.tduck.request.QueryFormResultRequest;
+import com.ltkj.tduck.service.UserFormDataService;
+import com.ltkj.tduck.service.UserFormViewCountService;
+import com.ltkj.tduck.utils.Result;
+import com.ltkj.tduck.utils.ValidatorUtils;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.security.PermitAll;
+import javax.servlet.http.HttpServletRequest;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
+
+/**
+ * 琛ㄥ崟鏁版嵁
+ *
+ * @author : smalljop
+ * @description : 琛ㄥ崟鏁版嵁椤� 褰撳墠鐢ㄦ埛鑷繁浣跨敤鎺ュ彛
+ * @create : 2020-11-18 18:17
+ **/
+
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+@RequestMapping("/user/form/data")
+public class UserFormResultController {
+    private final UserFormDataService formResultService;
+//    private final UserFormSettingService userFormSettingService;
+//    private final FormDataImportUtils formDataImportUtils;
+//    private final FormDataExportUtils formDataExportUtils;
+//    private final UserFormService userFormService;
+    private final UserFormViewCountService userFormViewCountService;
+//    private final MailService mailService;
+//    private final WxMpUserMsgService userMsgService;
+    private final ConcurrentMap<String, Integer> viewFormMap = new ConcurrentHashMap<>();
+
+
+
+    /**
+     * 鏍规嵁浣撴鍙疯幏鍙栭棶鍗疯褰�
+     */
+    @GetMapping("getRecordByTjNumber")
+    public AjaxResult getRecordByTjNumber(String tjNumber) {
+        LambdaQueryWrapper<UserFormDataEntity> wq=new LambdaQueryWrapper<>();
+        wq.eq(UserFormDataEntity::getTjNumber,tjNumber);
+        final List<UserFormDataEntity> list = formResultService.list(wq);
+        AjaxResult ajaxResult = new AjaxResult();
+        ajaxResult.put("code", 200);
+        ajaxResult.put("data", list);
+        ajaxResult.put("msg", null);
+        return ajaxResult;
+    }
+
+
+    /***
+     * 鏌ョ湅琛ㄥ崟
+     * 璁板綍鏌ョ湅鐨処P 缁熻鏌ョ湅鐢ㄦ埛鏁�
+     */
+    @GetMapping("view/{formKey}")
+    @PermitAll
+    public Result<Void> viewForm(HttpServletRequest request, @PathVariable("formKey") String formKey) {
+        if (viewFormMap.containsKey(formKey)) {
+            userFormViewCountService.increment(formKey);
+        } else {
+            // 涓嶅瓨鍦ㄥ垯娣诲姞
+            Long count = userFormViewCountService.count(formKey);
+            if (count == 0) {
+                UserFormViewCountEntity entity = new UserFormViewCountEntity();
+                entity.setFormKey(formKey);
+                entity.setCount(1L);
+                userFormViewCountService.save(entity);
+            }
+            viewFormMap.put(formKey, 1);
+        }
+        return Result.success();
+    }
+
+    /**
+     * 鏌ヨ鏁版嵁
+     *
+     * @param request 鏌ヨ鏉′欢
+     * @return 鏁版嵁
+     */
+    @PostMapping("query")
+    public Result queryFormDataTable(@RequestBody QueryFormResultRequest request) {
+//        FormAuthUtils.hasPermission(request.getFormKey());
+        return Result.success(formResultService.listFormDataTable(request));
+    }
+
+    /**
+     * 鑾峰彇鏌愭潯鏁版嵁璇︽儏
+     *
+     * @param dataId 鏁版嵁ID
+     * @return 鏁版嵁璇︽儏
+     */
+    @GetMapping("details/{dataId}")
+    @PermitAll
+    public Result getFormDataDetails(@PathVariable("dataId") String dataId) {
+        return formResultService.getFormDataDetails(dataId);
+    }
+//
+//
+//    /**
+//     * 濉啓闄勪欢瀵煎嚭
+//     *
+//     * @param request 璇锋眰
+//     * @return 鏂囦欢
+//     */
+//    @PostMapping("/download/file")
+//    public Result downloadFormResultFile(@RequestBody QueryFormResultRequest request) {
+//        return formResultService.downloadFormResultFile(request);
+//    }
+
+    /**
+     * 濉啓
+     *
+     * @param entity  濉啓鏁版嵁
+     * @param request 璇锋眰
+     * @return
+     */
+    @PostMapping("/create")
+    public AjaxResult createFormResult(@RequestBody UserFormDataEntity entity, HttpServletRequest request) {
+        ValidatorUtils.validateEntity(entity);
+        entity.setSubmitRequestIp(HttpUtils.getIpAddr(request));
+        // 濡傛灉宸茬粡鐧婚檰浜嗕篃璁板綍鐢ㄦ埛淇℃伅 try catch 閬垮厤鎶涘嚭寮傚父
+        entity.setCreateBy(SecurityUtils.getUserId() != null ? String.valueOf(SecurityUtils.getUserId()) : null);
+        Map<String, Object> result = formResultService.saveFormResult(entity);
+        return AjaxResult.success(result);
+    }
+
+
+    /**
+     * 鍏紑濉啓
+     *
+     * @param entity  濉啓鏁版嵁
+     * @param request 璇锋眰
+     */
+    @PostMapping("/public/create")
+    @PermitAll
+    public Result<Map<String, Object>> createPublicFormResult(@RequestBody UserFormDataEntity entity, HttpServletRequest request) {
+
+        ValidatorUtils.validateEntity(entity);
+        entity.setSubmitRequestIp(HttpUtils.getIpAddr(request));
+//        Result<Boolean> userFormSettingStatus = userFormSettingService.getUserFormWriteSettingStatus(entity.getFormKey(), entity.getSubmitRequestIp(), entity.getWxOpenId(), CommonConstants.ConstantNumber.ONE);
+//        if (StrUtil.isNotBlank(userFormSettingStatus.getMsg())) {
+//            return Result.failed(userFormSettingStatus.getMsg());
+//        }
+        // 濡傛灉宸茬粡鐧婚檰浜嗕篃璁板綍鐢ㄦ埛淇℃伅 try catch 閬垮厤鎶涘嚭寮傚父
+        entity.setCreateBy(SecurityUtils.getUserId() != null ? String.valueOf(SecurityUtils.getUserId()) : null);
+        Map<String, Object> result = formResultService.saveFormResult(entity);
+//        ThreadUtil.execAsync(() -> {
+//            sendWriteResultNotify(entity.getFormKey());
+//        });
+        return Result.success(result);
+//        return Result.success();
+    }
+
+//
+//    /**
+//     * 鎵归噺鍒犻櫎
+//     *
+//     * @param formKey    琛ㄥ崟key
+//     * @param dataIdList 鏁版嵁ID
+//     * @return Result
+//     */
+//    @PostMapping("/delete/{formKey}")
+//    public Result deleteFormData(@RequestBody List<String> dataIdList, @PathVariable("formKey") String formKey) {
+//        formResultService.deleteByIds(dataIdList, formKey);
+//        return Result.success();
+//    }
+
+
+//    /**
+//     * 鏇存柊
+//     *
+//     * @param entity  濉啓鏁版嵁
+//     * @param request 璇锋眰
+//     * @return Result
+//     */
+//    @PostMapping("/update")
+//    @PermitAll
+//    public Result<Void> updateFormResult(@RequestBody UserFormDataEntity entity, HttpServletRequest request) {
+//        ValidatorUtils.validateEntity(entity);
+//        try {
+//            entity.setUpdateBy(String.valueOf(SecurityUtils.getUserId()));
+//        } catch (Exception ignored) {
+//        }
+//        formResultService.updateFormResult(entity);
+//        return Result.success();
+//    }
+//
+//    /**
+//     * 涓嬭浇瀵煎叆妯℃澘
+//     *
+//     * @param response 鍝嶅簲
+//     * @param formKey  琛ㄥ崟key
+//     */
+//    @GetMapping("/import/template")
+//    public void downloadImportTemplate(HttpServletResponse response, String formKey) {
+//        formDataImportUtils.importTemplateExcel(response, formKey);
+//    }
+//
+//    /**
+//     * 瀵煎嚭琛ㄥ崟鏁版嵁
+//     */
+//    @PostMapping("export")
+//    public void exportFormData(@RequestBody ExportRequest.FormData exportRequest) {
+//        formDataExportUtils.exportData(exportRequest);
+//    }
+//
+//    /**
+//     * 瀵煎叆琛ㄥ崟鏁版嵁
+//     *
+//     * @param file 鏂囦欢
+//     * @return Result
+//     */
+//    @PostMapping("import")
+//    public Result importFormData(@RequestParam("file") MultipartFile file, UserFormDataEntity dataEntity) throws IOException {
+//        return Result.success(formDataImportUtils.importFile(file.getInputStream(), dataEntity.getFormKey()));
+//    }
+//
+//
+//    private void sendWriteResultNotify(String formKey) {
+//        FormSettingSchemaStruct formSettingSchema = userFormSettingService.getFormSettingSchema(formKey);
+//        if (ObjectUtil.isNull(formSettingSchema)) {
+//            return;
+//        }
+//        UserFormEntity form = userFormService.getByKey(formKey);
+//        if (StrUtil.isNotBlank(formSettingSchema.getNewWriteNotifyEmail())) {
+//            mailService.sendTemplateHtmlMail(formSettingSchema.getNewWriteNotifyEmail(), "鏂板洖澶嶉�氱煡", "mail/form-write-notify", MapUtil.of("projectName", form.getName()));
+//        }
+//
+//        if (StrUtil.isNotBlank(formSettingSchema.getNewWriteNotifyWx())) {
+//            List<String> openIdList = StrUtil.splitTrim(formSettingSchema.getNewWriteNotifyWx(), ";");
+//            openIdList.stream().forEach(openId -> {
+//                userMsgService.sendKfTextMsg("", openId, "鏀跺埌鏂扮殑鍙嶉锛岃鍘籔c绔煡鐪�");
+//            });
+//        }
+//    }
+
+}
diff --git a/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormSettingController.java b/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormSettingController.java
new file mode 100644
index 0000000..f30af9b
--- /dev/null
+++ b/ltkj-admin/src/main/java/com/ltkj/web/tduck/UserFormSettingController.java
@@ -0,0 +1,143 @@
+package com.ltkj.web.tduck;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.ltkj.common.utils.http.HttpUtils;
+import com.ltkj.tduck.domain.UserFormSettingEntity;
+import com.ltkj.tduck.request.CheckWritePwdRequest;
+import com.ltkj.tduck.service.UserFormSettingService;
+import com.ltkj.tduck.utils.CacheUtils;
+import com.ltkj.tduck.utils.Result;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.security.PermitAll;
+import javax.servlet.http.HttpServletRequest;
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟璁剧疆
+ *
+ * @author : smalljop
+ * @description : 琛ㄥ崟璁剧疆
+ * @create : 2020-11-18 18:17
+ **/
+@Slf4j
+@RestController
+@RequiredArgsConstructor
+public class UserFormSettingController {
+
+    private final UserFormSettingService userFormSettingService;
+//    private final WxMpUserService wxMpUserService;
+    private final CacheUtils cacheUtils;
+//    private final WxMpService wxMpService;
+
+
+    /**
+     * 淇濆瓨琛ㄥ崟璁剧疆
+     */
+    @PostMapping("/user/form/setting/save")
+    public Result<Boolean> saveFormSetting(@RequestBody Map<String, Object> setting) {
+        String formKey = setting.get("formKey").toString();
+//        FormAuthUtils.hasPermission(formKey);
+        return Result.success(userFormSettingService.saveFormSetting(setting));
+    }
+
+    /**
+     * 琛ㄥ崟鎻愪氦璁剧疆鏌ヨ
+     */
+    @GetMapping("/user/form/setting/{key}")
+    public Result<Map<String, Object>> queryFormSettingByKey(@PathVariable("key") String formKey) {
+        UserFormSettingEntity setting = userFormSettingService.getFormSettingByKey(formKey);
+        if (ObjectUtil.isNull(setting)) {
+            return Result.success();
+        }
+        Map<String, Object> settings = setting.getSettings();
+        settings.put(UserFormSettingEntity.Fields.formKey, formKey);
+        return Result.success(settings);
+    }
+
+
+    /**
+     * 褰撳墠濉啓璁剧疆鐨勭姸鎬�
+     *
+     * @param formKey  琛ㄥ崟key
+     * @param wxOpenId 寰俊openid
+     * @param type     绫诲瀷 1鍏紑濉啓 2.鎸囧畾濉啓
+     */
+    @GetMapping("/user/form/setting-status")
+    @PermitAll
+    public Result<Boolean> querySettingStatus(@RequestParam String formKey, @RequestParam(required = false) String wxOpenId, @RequestParam(required = false) Integer type, HttpServletRequest request) {
+        return userFormSettingService.getUserFormWriteSettingStatus(formKey, HttpUtils.getIpAddr(request), wxOpenId, type);
+    }
+
+
+    /**
+     * 濉啓寰俊閫氱煡浜岀淮鐮�
+     */
+    @GetMapping("/user/form/wx/notify-qrcode")
+    public Result<String> getWxNotifyQrCode(@RequestParam("key") String formKey) throws Exception {
+//        String loginSceneStr = JsonUtils.objToJson(new WxMpQrCodeGenRequest(WxMpQrCodeGenRequest.QrCodeType.SUB_NOTIFY, formKey));
+//        //5鍒嗛挓鏈夋晥
+//        WxMpQrCodeTicket ticket = wxMpService.getQrcodeService().qrCodeCreateTmpTicket(loginSceneStr, 10 * 60);
+//        String subNotifyQrcodeUrl = wxMpService.getQrcodeService().qrCodePictureUrl(ticket.getTicket());
+//        return Result.success(subNotifyQrcodeUrl);
+        return Result.success();
+    }
+
+
+    /**
+     * 濉啓寰俊閫氱煡浜岀淮鐮�
+     */
+    @PostMapping("/user/form/wx/delete/notify-user")
+    public Result<Boolean> deleteWxNotifyQrCode(@RequestParam("key") String key, @RequestParam("openId") String openId) {
+//        cacheUtils.removeList(StrUtil.format(WxMpRedisKeyConstants.WX_MP_SUB_NOTIFY, key), openId);
+        return Result.success(true);
+    }
+
+    /**
+     * 鑾峰彇琛ㄥ崟寰俊閫氱煡鐢ㄦ埛
+     */
+    @GetMapping("/user/form/wx/notify-user")
+    public Result getWxNotifyUser(@RequestParam("key") String formKey, @RequestParam(required = false) String openIdStr) {
+//        Set<Object> subNotifyUsers = null;
+//        if (StrUtil.isNotBlank(openIdStr)) {
+//            subNotifyUsers = Sets.newHashSet(StrUtil.splitTrim(openIdStr, ";"));
+//        } else {
+//            List coll = cacheUtils.getList(StrUtil.format(WxMpRedisKeyConstants.WX_MP_SUB_NOTIFY, formKey), String.class);
+//            subNotifyUsers = Collections.singleton(coll.stream().collect(Collectors.toSet()));
+//        }
+//        return Result.success(wxMpUserService.listWxMpUserByOpenId(subNotifyUsers).stream().map(item -> new WxMpUserVO(item.getNickname(), item.getHeadImgUrl(), item.getOpenId())).collect(Collectors.toList()));
+        return Result.success();
+    }
+
+
+    /**
+     * 鍏紑鎺ュ彛
+     * 琛ㄥ崟濉啓鏃堕渶瑕佺殑璁剧疆
+     */
+    @GetMapping("/user/form/public/settings/{key}")
+    @PermitAll
+    public Result queryPublicFormSettingByKey(@PathVariable("key") String formKey) {
+//        FormSettingSchemaStruct formSettingSchema = userFormSettingService.getFormSettingSchema(formKey);
+        return Result.success();
+    }
+
+    /**
+     * 鍏紑鎺ュ彛
+     * 妫�鏌ュ~鍐欏瘑鐮佹槸鍚︽纭�
+     */
+    @PostMapping("/user/form/public/checkWritePwd")
+    @PermitAll
+    public Result<Boolean> checkWritePwd(@RequestBody @Validated CheckWritePwdRequest request) {
+//        FormSettingSchemaStruct formSettingSchema = userFormSettingService.getFormSettingSchema(request.getFormKey());
+//        if (formSettingSchema.getWritePassword().equals(request.getPassword())) {
+//            return Result.success(true);
+//        }
+//        return Result.failed("瀵嗙爜杈撳叆閿欒");
+        return Result.success(true);
+    }
+
+
+}
diff --git a/ltkj-admin/src/main/java/com/ltkj/web/tduck/WxJsApiController.java b/ltkj-admin/src/main/java/com/ltkj/web/tduck/WxJsApiController.java
new file mode 100644
index 0000000..0273389
--- /dev/null
+++ b/ltkj-admin/src/main/java/com/ltkj/web/tduck/WxJsApiController.java
@@ -0,0 +1,74 @@
+package com.ltkj.web.tduck;
+
+import cn.hutool.core.util.StrUtil;
+import cn.hutool.core.util.URLUtil;
+import com.ltkj.tduck.utils.Result;
+import lombok.AllArgsConstructor;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RequestParam;
+import org.springframework.web.bind.annotation.RestController;
+
+import javax.annotation.security.PermitAll;
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author : smalljop
+ * @description : 寰俊鍏紬鍙风綉椤�
+ * @create : 2020-12-02 13:40
+ **/
+@AllArgsConstructor
+@RestController
+@RequestMapping("/wx/jsapi/")
+public class WxJsApiController {
+//    private final WxMpService wxService;
+
+
+    /**
+     * 鐢ㄦ埛鎺堟潈url
+     *
+     * @return hcah
+     */
+    @GetMapping("/authorization/url")
+    @PermitAll
+    public Result getAuthorizationUrl(@RequestParam @NotBlank String url) {
+        String appId = "11111";
+        String authorizationUrl = StrUtil.format("https://open.weixin.qq.com/connect/oauth2/authorize?appid={}&redirect_uri={}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect", appId, URLUtil.encode(url));
+        return Result.success(authorizationUrl);
+    }
+
+
+    /**
+     * 鏍规嵁code鑾峰彇鐢ㄦ埛淇℃伅
+     *
+     * @param code
+     * @return
+     */
+    @GetMapping("/authorization/user/info")
+    @PermitAll
+    public Result greetUser(@RequestParam @NotBlank String code)  {
+//        WxOAuth2UserInfo userInfo = null;
+//        try {
+//            WxOAuth2AccessToken accessToken = wxService.getOAuth2Service().getAccessToken(code);
+//            userInfo = wxService.getOAuth2Service().getUserInfo(accessToken, null);
+//        } catch (WxErrorException e) {
+//            return Result.success();
+//        }
+//        return Result.success(userInfo);
+        return Result.success();
+    }
+
+
+    /**
+     * 鑾峰彇jsapi绛惧悕
+     */
+    @GetMapping("/signature")
+    @PermitAll
+    public Result getSignature(@RequestParam String url) throws Exception {
+//        WxJsapiSignature signature = wxService.createJsapiSignature(url);
+//        return Result.success(signature);
+        return Result.success();
+    }
+
+
+}
diff --git a/ltkj-admin/src/main/resources/application.yml b/ltkj-admin/src/main/resources/application.yml
index 57257f7..9dd66dd 100644
--- a/ltkj-admin/src/main/resources/application.yml
+++ b/ltkj-admin/src/main/resources/application.yml
@@ -70,6 +70,10 @@
     restart:
       # 鐑儴缃插紑鍏�
       enabled: true
+  cache:
+    type: ehcache
+    ehcache:
+      config: classpath:config/ehcache.xml
   # redis 閰嶇疆
 #  redis:
 #    # 鍦板潃
diff --git a/ltkj-admin/src/main/resources/config/ehcache.xml b/ltkj-admin/src/main/resources/config/ehcache.xml
new file mode 100644
index 0000000..d352174
--- /dev/null
+++ b/ltkj-admin/src/main/resources/config/ehcache.xml
@@ -0,0 +1,57 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:noNamespaceSchemaLocation="ehcache.xsd">
+    <!--timeToIdleSeconds 褰撶紦瀛橀棽缃畁绉掑悗閿�姣� -->
+    <!--timeToLiveSeconds 褰撶紦瀛樺瓨娲籲绉掑悗閿�姣� -->
+    <!-- 缂撳瓨閰嶇疆
+        name:缂撳瓨鍚嶇О銆�
+        maxElementsInMemory锛氱紦瀛樻渶澶т釜鏁般��
+        eternal:瀵硅薄鏄惁姘镐箙鏈夋晥锛屼竴浣嗚缃簡锛宼imeout灏嗕笉璧蜂綔鐢ㄣ��
+        timeToIdleSeconds锛氳缃璞″湪澶辨晥鍓嶇殑鍏佽闂茬疆鏃堕棿锛堝崟浣嶏細绉掞級銆備粎褰揺ternal=false瀵硅薄涓嶆槸姘镐箙鏈夋晥鏃朵娇鐢紝鍙�夊睘鎬э紝榛樿鍊兼槸0锛屼篃灏辨槸鍙棽缃椂闂存棤绌峰ぇ銆�
+        timeToLiveSeconds锛氳缃璞″湪澶辨晥鍓嶅厑璁稿瓨娲绘椂闂达紙鍗曚綅锛氱锛夈�傛渶澶ф椂闂翠粙浜庡垱寤烘椂闂村拰澶辨晥鏃堕棿涔嬮棿銆備粎褰揺ternal=false瀵硅薄涓嶆槸姘镐箙鏈夋晥鏃朵娇鐢紝榛樿鏄�0.锛屼篃灏辨槸瀵硅薄瀛樻椿鏃堕棿鏃犵┓澶с��
+        overflowToDisk锛氬綋鍐呭瓨涓璞℃暟閲忚揪鍒癿axElementsInMemory鏃讹紝Ehcache灏嗕細瀵硅薄鍐欏埌纾佺洏涓�� diskSpoolBufferSizeMB锛氳繖涓弬鏁拌缃瓺iskStore锛堢鐩樼紦瀛橈級鐨勭紦瀛樺尯澶у皬銆傞粯璁ゆ槸30MB銆傛瘡涓狢ache閮藉簲璇ユ湁鑷繁鐨勪竴涓紦鍐插尯銆�
+        maxElementsOnDisk锛氱‖鐩樻渶澶х紦瀛樹釜鏁般��
+        diskPersistent锛氭槸鍚︾紦瀛樿櫄鎷熸満閲嶅惎鏈熸暟鎹� Whether the disk
+        store persists between restarts of the Virtual Machine. The default value
+        is false.
+        diskExpiryThreadIntervalSeconds锛氱鐩樺け鏁堢嚎绋嬭繍琛屾椂闂撮棿闅旓紝榛樿鏄�120绉掋��  memoryStoreEvictionPolicy锛氬綋杈惧埌maxElementsInMemory闄愬埗鏃讹紝Ehcache灏嗕細鏍规嵁鎸囧畾鐨勭瓥鐣ュ幓娓呯悊鍐呭瓨銆傞粯璁ょ瓥鐣ユ槸
+LRU锛堟渶杩戞渶灏戜娇鐢級銆備綘鍙互璁剧疆涓篎IFO锛堝厛杩涘厛鍑猴級鎴栨槸LFU锛堣緝灏戜娇鐢級銆�
+        clearOnFlush锛氬唴瀛樻暟閲忔渶澶ф椂鏄惁娓呴櫎銆� -->
+    <!-- 纾佺洏缂撳瓨浣嶇疆 -->
+    <diskStore path="java.io.tmpdir"/>
+    <!-- 榛樿缂撳瓨 -->
+    <defaultCache
+            maxElementsInMemory="10000"
+            eternal="false"
+            timeToIdleSeconds="120"
+            timeToLiveSeconds="120"
+            maxElementsOnDisk="10000000"
+            diskExpiryThreadIntervalSeconds="120"
+            memoryStoreEvictionPolicy="LRU">
+
+        <persistence strategy="localTempSwap"/>
+    </defaultCache>
+
+    <!--    鎸佷箙鍖朿ache-->
+    <cache name="eternal_cache"
+           maxElementsInMemory="10000"
+           eternal="true"
+           timeToIdleSeconds="120"
+           timeToLiveSeconds="120"
+           overflowToDisk="true"
+           diskPersistent="true"
+           diskExpiryThreadIntervalSeconds="10"/>
+
+    <!-- 涓存椂cache -->
+    <cache name="temp_cache"
+           maxElementsInMemory="10000"
+           eternal="false"
+           timeToIdleSeconds="300"
+           timeToLiveSeconds="300"
+           maxElementsOnDisk="10000000"
+           diskExpiryThreadIntervalSeconds="120"
+           memoryStoreEvictionPolicy="LRU">
+        <persistence strategy="localTempSwap"/>
+    </cache>
+
+</ehcache>
\ No newline at end of file
diff --git a/ltkj-common/pom.xml b/ltkj-common/pom.xml
index 572837d..d8ce7e4 100644
--- a/ltkj-common/pom.xml
+++ b/ltkj-common/pom.xml
@@ -22,6 +22,27 @@
 <!--        </repository>-->
 <!--    </repositories>-->
     <dependencies>
+
+        <!--浠ヤ笅tduck-->
+        <dependency>
+            <groupId>com.aventrix.jnanoid</groupId>
+            <artifactId>jnanoid</artifactId>
+            <version>2.0.0</version>
+        </dependency>
+        <dependency>
+            <groupId>com.fasterxml.jackson.datatype</groupId>
+            <artifactId>jackson-datatype-jsr310</artifactId>
+            <version>2.16.0</version>
+        </dependency>
+        <!-- ehcache缂撳瓨 -->
+        <dependency>
+            <groupId>net.sf.ehcache</groupId>
+            <artifactId>ehcache</artifactId>
+            <version>2.9.1</version><!--$NO-MVN-MAN-VER$ -->
+        </dependency>
+        <!--浠ヤ笂tduck-->
+
+
 <!--        <dependency>-->
 <!--            <groupId>e-iceblue</groupId>-->
 <!--            <artifactId>spire.pdf</artifactId>-->
diff --git a/ltkj-common/src/main/java/com/ltkj/common/utils/http/HttpUtils.java b/ltkj-common/src/main/java/com/ltkj/common/utils/http/HttpUtils.java
index 53498e2..afa1ee2 100644
--- a/ltkj-common/src/main/java/com/ltkj/common/utils/http/HttpUtils.java
+++ b/ltkj-common/src/main/java/com/ltkj/common/utils/http/HttpUtils.java
@@ -17,7 +17,10 @@
 import javax.net.ssl.SSLSession;
 import javax.net.ssl.TrustManager;
 import javax.net.ssl.X509TrustManager;
+import javax.servlet.http.HttpServletRequest;
 
+import cn.hutool.core.util.CharUtil;
+import cn.hutool.core.util.StrUtil;
 import com.ltkj.common.constant.Constants;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -216,4 +219,43 @@
             return true;
         }
     }
-}
\ No newline at end of file
+
+
+
+    /**
+     * 鑾峰彇璇锋眰IP鍦板潃
+     *
+     * @param request
+     * @return
+     */
+    public static String getIpAddr(HttpServletRequest request) {
+        if (request == null) {
+            return "unknown";
+        }
+        String ip = request.getHeader("x-forwarded-for");
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Forwarded-For");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("WL-Proxy-Client-IP");
+        }
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getHeader("X-Real-IP");
+        }
+
+        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
+            ip = request.getRemoteAddr();
+        }
+        //"***.***.***.***".length() = 15
+        if (StrUtil.isNotBlank(ip) && ip.length() > 15) {
+            if (ip.indexOf(CharUtil.COMMA) > 0) {
+                ip = ip.substring(0, ip.indexOf(","));
+            }
+        }
+        //澶勭悊鑾峰彇澶氫釜ip鍦板潃鎯呭喌 nginx澶氬眰浠g悊浼氬嚭鐜板涓猧p 绗竴涓负鐪熷疄ip鍦板潃
+        return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
+    }
+}
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyOptions.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyOptions.java
index 57a874b..73b3640 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyOptions.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyOptions.java
@@ -39,7 +39,7 @@
      */
     @ApiModelProperty(value = "闂")
     @Excel(name = "闂")
-    private Long qid;
+    private String qid;
 
     /**
      * 閫夐」
@@ -56,37 +56,7 @@
     private String score;
 
 
-    public void setOid(Long oid) {
-        this.oid = oid;
-    }
 
-    public Long getOid() {
-        return oid;
-    }
-
-    public void setQid(Long qid) {
-        this.qid = qid;
-    }
-
-    public Long getQid() {
-        return qid;
-    }
-
-    public void setOoption(String ooption) {
-        this.ooption = ooption;
-    }
-
-    public String getOoption() {
-        return ooption;
-    }
-
-    public void setScore(String score) {
-        this.score = score;
-    }
-
-    public String getScore() {
-        return score;
-    }
 
 
 
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyQuestion.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyQuestion.java
index 5c40edd..c8fe3b4 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyQuestion.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyQuestion.java
@@ -32,10 +32,10 @@
     /**
      * id
      */
-    @ApiModelProperty(value = "涓婚敭id")
-    @TableId
-    @JsonSerialize(using = ToStringSerializer.class)
-    private Long qid;
+//    @ApiModelProperty(value = "涓婚敭id")
+//    @TableId
+//    @JsonSerialize(using = ToStringSerializer.class)
+    private String qid;
 
     /**
      * 闂
@@ -58,6 +58,16 @@
     @Excel(name = "鏄惁蹇呭~",dictType="sys_yes_no")
     private String isRequired;
 
+
+    private String keywords;
+
+    private String sort;
+
+    private Long mid;
+
+    @TableField(exist = false)
+    private TjSurveyTemplate template;
+
     /**
      * 闂嵎閫夐」淇℃伅
      */
@@ -65,47 +75,7 @@
     @TableField(exist = false)
     private List<TjSurveyOptions> tjSurveyOptionsList;
 
-    public void setQid(Long qid) {
-        this.qid = qid;
-    }
 
-    public Long getQid() {
-        return qid;
-    }
-
-    public void setQuestion(String question) {
-        this.question = question;
-    }
-
-    public String getQuestion() {
-        return question;
-    }
-
-    public void setType(String type) {
-        this.type = type;
-    }
-
-    public String getType() {
-        return type;
-    }
-
-    public void setIsRequired(String isRequired) {
-        this.isRequired = isRequired;
-    }
-
-    public String getIsRequired() {
-        return isRequired;
-    }
-
-
-
-    public List<TjSurveyOptions> getTjSurveyOptionsList() {
-        return tjSurveyOptionsList;
-    }
-
-    public void setTjSurveyOptionsList(List<TjSurveyOptions> tjSurveyOptionsList) {
-        this.tjSurveyOptionsList = tjSurveyOptionsList;
-    }
 
     @Override
     public String toString() {
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyRecord.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyRecord.java
index aee77f4..c6c145e 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyRecord.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyRecord.java
@@ -110,86 +110,14 @@
     @Excel(name = "鏍囧織")
     private String fromBy;
 
+    private Long fmId;
+
     /**
      * 闂嵎璁板綍璇︽儏淇℃伅
      */
     @ApiModelProperty(value = "闂嵎璁板綍璇︽儏淇℃伅")
     @TableField(exist = false)
     private List<TjSurveyRecordDetail> tjSurveyRecordDetailList;
-
-    public void setRid(Long rid) {
-        this.rid = rid;
-    }
-
-    public Long getRid() {
-        return rid;
-    }
-
-    public void setTjnumber(Long tjnumber) {
-        this.tjnumber = tjnumber;
-    }
-
-    public Long getTjnumber() {
-        return tjnumber;
-    }
-
-    public void setPhone(String phone) {
-        this.phone = phone;
-    }
-
-    public String getPhone() {
-        return phone;
-    }
-
-    public void setUserName(String userName) {
-        this.userName = userName;
-    }
-
-    public String getUserName() {
-        return userName;
-    }
-
-    public void setMid(Long mid) {
-        this.mid = mid;
-    }
-
-    public Long getMid() {
-        return mid;
-    }
-
-    public void setMname(String mname) {
-        this.mname = mname;
-    }
-
-    public String getMname() {
-        return mname;
-    }
-
-    public void setQid(Long qid) {
-        this.qid = qid;
-    }
-
-    public Long getQid() {
-        return qid;
-    }
-
-    public void setQname(String qname) {
-        this.qname = qname;
-    }
-
-    public String getQname() {
-        return qname;
-    }
-
-
-
-    public List<TjSurveyRecordDetail> getTjSurveyRecordDetailList() {
-        return tjSurveyRecordDetailList;
-    }
-
-    public void setTjSurveyRecordDetailList(List<TjSurveyRecordDetail> tjSurveyRecordDetailList) {
-        this.tjSurveyRecordDetailList = tjSurveyRecordDetailList;
-    }
 
     @Override
     public String toString() {
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTempQues.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTempQues.java
index 5177fe4..02d850c 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTempQues.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTempQues.java
@@ -46,7 +46,7 @@
      */
     @ApiModelProperty(value = "闂id")
     @Excel(name = "闂id")
-    private Long qid;
+    private String qid;
 
     /**
      * 闂鍚�
@@ -56,37 +56,6 @@
     private String qname;
 
 
-    public void setTqid(Long tqid) {
-        this.tqid = tqid;
-    }
-
-    public Long getTqid() {
-        return tqid;
-    }
-
-    public void setMid(Long mid) {
-        this.mid = mid;
-    }
-
-    public Long getMid() {
-        return mid;
-    }
-
-    public void setQid(Long qid) {
-        this.qid = qid;
-    }
-
-    public Long getQid() {
-        return qid;
-    }
-
-    public void setQname(String qname) {
-        this.qname = qname;
-    }
-
-    public String getQname() {
-        return qname;
-    }
 
 
     @Override
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTemplate.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTemplate.java
index b956aa5..45b6d1f 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTemplate.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/domain/TjSurveyTemplate.java
@@ -53,44 +53,22 @@
 
 
     /**
+     * 琛ㄥ崟璁捐缁戝畾
+     */
+    private String designId;
+
+
+    /*鍚敤鏍囧織*/
+    private String qybz;
+
+
+    /**
      * 闂嵎妯℃澘闂淇℃伅
      */
     @ApiModelProperty(value = "闂嵎妯℃澘闂淇℃伅")
     @TableField(exist = false)
     private List<TjSurveyTempQues> tjSurveyTempQuesList;
 
-    public void setMid(Long mid) {
-        this.mid = mid;
-    }
-
-    public Long getMid() {
-        return mid;
-    }
-
-    public void setTempName(String tempName) {
-        this.tempName = tempName;
-    }
-
-    public String getTempName() {
-        return tempName;
-    }
-
-    public void setTempType(String tempType) {
-        this.tempType = tempType;
-    }
-
-    public String getTempType() {
-        return tempType;
-    }
-
-
-    public List<TjSurveyTempQues> getTjSurveyTempQuesList() {
-        return tjSurveyTempQuesList;
-    }
-
-    public void setTjSurveyTempQuesList(List<TjSurveyTempQues> tjSurveyTempQuesList) {
-        this.tjSurveyTempQuesList = tjSurveyTempQuesList;
-    }
 
     @Override
     public String toString() {
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyQuestionMapper.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyQuestionMapper.java
index 9a8f8a0..7641e46 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyQuestionMapper.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyQuestionMapper.java
@@ -1,11 +1,13 @@
 package com.ltkj.hosp.mapper;
 
-import java.util.List;
-
 import com.baomidou.mybatisplus.core.mapper.BaseMapper;
-import com.ltkj.hosp.domain.TjSurveyQuestion;
 import com.ltkj.hosp.domain.TjSurveyOptions;
+import com.ltkj.hosp.domain.TjSurveyQuestion;
+import com.ltkj.hosp.domain.TjSurveyTempQues;
 import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
 
 /**
  * 闂嵎闂Mapper鎺ュ彛
@@ -21,7 +23,12 @@
      * @param qid 闂嵎闂涓婚敭
      * @return 闂嵎闂
      */
-    public TjSurveyQuestion selectTjSurveyQuestionByQid(Long qid);
+    public TjSurveyQuestion selectTjSurveyQuestionByQid(String qid);
+
+
+    /*鏍规嵁闂鏌ヨ閫夐」闆嗗悎*/
+    public List<TjSurveyOptions> selectOptionsByQid(String qid);
+
 
     /**
      * 鏌ヨ闂嵎闂鍒楄〃
@@ -39,6 +46,15 @@
      */
     public int insertTjSurveyQuestion(TjSurveyQuestion tjSurveyQuestion);
 
+
+    /**
+     * 鏂板闂嵎
+     *
+     * @param tjSurveyOptions 闂嵎
+     * @return 缁撴灉
+     */
+    public int insertTjSurveyOptions(TjSurveyOptions tjSurveyOptions);
+
     /**
      * 淇敼闂嵎闂
      *
@@ -53,7 +69,10 @@
      * @param qid 闂嵎闂涓婚敭
      * @return 缁撴灉
      */
-    public int deleteTjSurveyQuestionByQid(Long qid);
+    public int deleteTjSurveyQuestionByQid(String qid);
+
+
+    public int deleteTjSurveyQuestionByMid(Long mid);
 
     /**
      * 鎵归噺鍒犻櫎闂嵎闂
@@ -61,30 +80,37 @@
      * @param qids 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
      * @return 缁撴灉
      */
-    public int deleteTjSurveyQuestionByQids(Long[] qids);
+    public int deleteTjSurveyQuestionByQids(String[] qids);
 
-        /**
-         * 鎵归噺鍒犻櫎闂嵎閫夐」
-         *
-         * @param qids 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
-         * @return 缁撴灉
-         */
-        public int deleteTjSurveyOptionsByQids(Long[] qids);
+    /**
+     * 鎵归噺鍒犻櫎闂嵎閫夐」
+     *
+     * @param qids 闇�瑕佸垹闄ょ殑鏁版嵁涓婚敭闆嗗悎
+     * @return 缁撴灉
+     */
+    public int deleteTjSurveyOptionsByQids(String[] qids);
 
-        /**
-         * 鎵归噺鏂板闂嵎閫夐」
-         *
-         * @param tjSurveyOptionsList 闂嵎閫夐」鍒楄〃
-         * @return 缁撴灉
-         */
-        public int batchTjSurveyOptions(List<TjSurveyOptions> tjSurveyOptionsList);
+    /**
+     * 鎵归噺鏂板闂嵎閫夐」
+     *
+     * @param tjSurveyOptionsList 闂嵎閫夐」鍒楄〃
+     * @return 缁撴灉
+     */
+    public int batchTjSurveyOptions(List<TjSurveyOptions> tjSurveyOptionsList);
 
 
-        /**
-         * 閫氳繃闂嵎闂涓婚敭鍒犻櫎闂嵎閫夐」淇℃伅
-         *
-         * @param qid 闂嵎闂ID
-         * @return 缁撴灉
-         */
-        public int deleteTjSurveyOptionsByQid(Long qid);
+    /**
+     * 閫氳繃闂嵎闂涓婚敭鍒犻櫎闂嵎閫夐」淇℃伅
+     *
+     * @param qid 闂嵎闂ID
+     * @return 缁撴灉
+     */
+    public int deleteTjSurveyOptionsByQid(String qid);
+
+
+    @Select("SELECT * FROM tj_survey_temp_ques a WHERE a.mid=#{mid} AND a.deleted=0")
+    List<TjSurveyTempQues> selectOptionsByMid(String mid);
+
+
+    List<TjSurveyQuestion> getOptionsByMid(String mid);
 }
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyTemplateMapper.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyTemplateMapper.java
index 7646c07..3b6e314 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyTemplateMapper.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/mapper/TjSurveyTemplateMapper.java
@@ -24,6 +24,11 @@
      */
     public TjSurveyTemplate selectTjSurveyTemplateByMid(Long mid);
 
+    public TjSurveyTemplate selectTemplateByMid1(Long mid);
+    public int qybzTjSurveyTemplateByQy(Long mid);
+    public int qybzTjSurveyTemplateByJy(Long mid);
+
+
     /**
      * 鏌ヨ闂嵎妯℃澘鍒楄〃
      *
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyQuestionService.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyQuestionService.java
index 88a78ef..915d03b 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyQuestionService.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyQuestionService.java
@@ -1,10 +1,11 @@
 package com.ltkj.hosp.service;
 
-import java.util.List;
-
 import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.hosp.domain.TjSurveyOptions;
 import com.ltkj.hosp.domain.TjSurveyQuestion;
-import com.ltkj.hosp.domain.TjTeamSelectRecord;
+import com.ltkj.hosp.domain.TjSurveyTempQues;
+
+import java.util.List;
 
 /**
  * 闂嵎闂Service鎺ュ彛
@@ -19,8 +20,9 @@
      * @param qid 闂嵎闂涓婚敭
      * @return 闂嵎闂
      */
-    public TjSurveyQuestion selectTjSurveyQuestionByQid(Long qid);
+    public TjSurveyQuestion selectTjSurveyQuestionByQid(String qid);
 
+    public List<TjSurveyOptions> selectOptionsByQid(String qid);
     /**
      * 鏌ヨ闂嵎闂鍒楄〃
      *
@@ -51,7 +53,7 @@
      * @param qids 闇�瑕佸垹闄ょ殑闂嵎闂涓婚敭闆嗗悎
      * @return 缁撴灉
      */
-    public int deleteTjSurveyQuestionByQids(Long[] qids);
+    public int deleteTjSurveyQuestionByQids(String[] qids);
 
     /**
      * 鍒犻櫎闂嵎闂淇℃伅
@@ -59,5 +61,10 @@
      * @param qid 闂嵎闂涓婚敭
      * @return 缁撴灉
      */
-    public int deleteTjSurveyQuestionByQid(Long qid);
+    public int deleteTjSurveyQuestionByQid(String qid);
+
+
+    List<TjSurveyTempQues> selectOptionsByMid(String mid);
+
+    List<TjSurveyQuestion> getOptionsByMid(String mid);
 }
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyTemplateService.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyTemplateService.java
index 651f487..bc7c223 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyTemplateService.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/ITjSurveyTemplateService.java
@@ -21,6 +21,11 @@
      */
     public TjSurveyTemplate selectTjSurveyTemplateByMid(Long mid);
 
+    public TjSurveyTemplate selectTemplateByMid1(Long mid);
+
+    public int qybzTjSurveyTemplateByQy(Long mid);
+    public int qybzTjSurveyTemplateByJy(Long mid);
+
     /**
      * 鏌ヨ闂嵎妯℃澘鍒楄〃
      *
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyQuestionServiceImpl.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyQuestionServiceImpl.java
index c00d7ff..fff56f8 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyQuestionServiceImpl.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyQuestionServiceImpl.java
@@ -1,22 +1,20 @@
 package com.ltkj.hosp.service.impl;
 
-import java.util.List;
-
 import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
 import com.ltkj.common.utils.DateUtils;
-import com.ltkj.hosp.domain.TjTeamSelectRecord;
-import com.ltkj.hosp.mapper.TjTeamSelectRecordMapper;
+import com.ltkj.common.utils.SecurityUtils;
+import com.ltkj.common.utils.StringUtils;
+import com.ltkj.hosp.domain.TjSurveyOptions;
+import com.ltkj.hosp.domain.TjSurveyQuestion;
+import com.ltkj.hosp.domain.TjSurveyTempQues;
+import com.ltkj.hosp.mapper.TjSurveyQuestionMapper;
+import com.ltkj.hosp.service.ITjSurveyQuestionService;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
 
 import java.util.ArrayList;
-
-import com.ltkj.common.utils.StringUtils;
-import org.springframework.transaction.annotation.Transactional;
-import com.ltkj.hosp.domain.TjSurveyOptions;
-import com.ltkj.hosp.mapper.TjSurveyQuestionMapper;
-import com.ltkj.hosp.domain.TjSurveyQuestion;
-import com.ltkj.hosp.service.ITjSurveyQuestionService;
+import java.util.List;
 
 /**
  * 闂嵎闂Service涓氬姟灞傚鐞�
@@ -36,8 +34,13 @@
      * @return 闂嵎闂
      */
     @Override
-    public TjSurveyQuestion selectTjSurveyQuestionByQid(Long qid) {
+    public TjSurveyQuestion selectTjSurveyQuestionByQid(String qid) {
         return tjSurveyQuestionMapper.selectTjSurveyQuestionByQid(qid);
+    }
+
+    @Override
+    public List<TjSurveyOptions> selectOptionsByQid(String qid) {
+        return tjSurveyQuestionMapper.selectOptionsByQid(qid);
     }
 
     /**
@@ -61,7 +64,9 @@
     @Override
     public int insertTjSurveyQuestion(TjSurveyQuestion tjSurveyQuestion) {
         tjSurveyQuestion.setCreateTime(DateUtils.getNowDate());
+        tjSurveyQuestion.setCreateBy(SecurityUtils.getLoginUser().getUsername());
         int rows = tjSurveyQuestionMapper.insertTjSurveyQuestion(tjSurveyQuestion);
+        System.out.println(tjSurveyQuestion);
         insertTjSurveyOptions(tjSurveyQuestion);
         return rows;
     }
@@ -76,8 +81,7 @@
     @Override
     public int updateTjSurveyQuestion(TjSurveyQuestion tjSurveyQuestion) {
         tjSurveyQuestion.setUpdateTime(DateUtils.getNowDate());
-        tjSurveyQuestionMapper.deleteTjSurveyOptionsByQid(tjSurveyQuestion.getQid())
-        ;
+        tjSurveyQuestionMapper.deleteTjSurveyOptionsByQid(tjSurveyQuestion.getQid());
         insertTjSurveyOptions(tjSurveyQuestion);
         return tjSurveyQuestionMapper.updateTjSurveyQuestion(tjSurveyQuestion);
     }
@@ -90,7 +94,7 @@
      */
     @Transactional
     @Override
-    public int deleteTjSurveyQuestionByQids(Long[] qids) {
+    public int deleteTjSurveyQuestionByQids(String[] qids) {
         tjSurveyQuestionMapper.deleteTjSurveyOptionsByQids(qids);
         return tjSurveyQuestionMapper.deleteTjSurveyQuestionByQids(qids);
     }
@@ -103,9 +107,19 @@
      */
     @Transactional
     @Override
-    public int deleteTjSurveyQuestionByQid(Long qid) {
+    public int deleteTjSurveyQuestionByQid(String qid) {
         tjSurveyQuestionMapper.deleteTjSurveyOptionsByQid(qid);
         return tjSurveyQuestionMapper.deleteTjSurveyQuestionByQid(qid);
+    }
+
+    @Override
+    public List<TjSurveyTempQues> selectOptionsByMid(String mid) {
+        return tjSurveyQuestionMapper.selectOptionsByMid(mid);
+    }
+
+    @Override
+    public List<TjSurveyQuestion> getOptionsByMid(String mid) {
+        return tjSurveyQuestionMapper.getOptionsByMid(mid);
     }
 
     /**
@@ -115,19 +129,21 @@
      */
     public void insertTjSurveyOptions(TjSurveyQuestion tjSurveyQuestion) {
         List<TjSurveyOptions> tjSurveyOptionsList = tjSurveyQuestion.getTjSurveyOptionsList();
-        Long qid = tjSurveyQuestion.getQid();
+        String qid = tjSurveyQuestion.getQid();
         if (StringUtils.isNotNull(tjSurveyOptionsList)) {
             List<TjSurveyOptions> list = new ArrayList<TjSurveyOptions>();
             for (TjSurveyOptions tjSurveyOptions : tjSurveyOptionsList) {
                 tjSurveyOptions.setQid(qid);
                 tjSurveyOptions.setDeleted(0);
+                tjSurveyOptions.setCreateBy(SecurityUtils.getLoginUser().getUsername());
+                tjSurveyOptions.setCreateTime(DateUtils.getNowDate());
                 list.add(tjSurveyOptions);
             }
             if (list.size() > 0) {
                 for (TjSurveyOptions tjSurveyOptions : list) {
                     tjSurveyOptions.setDeleted(0);
+                    tjSurveyQuestionMapper.insertTjSurveyOptions(tjSurveyOptions);
                 }
-                tjSurveyQuestionMapper.batchTjSurveyOptions(list);
             }
         }
     }
diff --git a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyTemplateServiceImpl.java b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyTemplateServiceImpl.java
index 0303975..81a83ee 100644
--- a/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyTemplateServiceImpl.java
+++ b/ltkj-hosp/src/main/java/com/ltkj/hosp/service/impl/TjSurveyTemplateServiceImpl.java
@@ -40,6 +40,22 @@
         return tjSurveyTemplateMapper.selectTjSurveyTemplateByMid(mid);
     }
 
+    @Override
+    public TjSurveyTemplate selectTemplateByMid1(Long mid) {
+        return tjSurveyTemplateMapper.selectTemplateByMid1(mid);
+    }
+
+    @Override
+    public int qybzTjSurveyTemplateByQy(Long mid) {
+        return tjSurveyTemplateMapper.qybzTjSurveyTemplateByQy(mid);
+    }
+
+    @Override
+    public int qybzTjSurveyTemplateByJy(Long mid) {
+        return tjSurveyTemplateMapper.qybzTjSurveyTemplateByJy(mid);
+    }
+
+
     /**
      * 鏌ヨ闂嵎妯℃澘鍒楄〃
      *
diff --git a/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyQuestionMapper.xml b/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyQuestionMapper.xml
index 7f2b80e..1695842 100644
--- a/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyQuestionMapper.xml
+++ b/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyQuestionMapper.xml
@@ -15,6 +15,9 @@
         <result property="updateBy" column="update_by"/>
         <result property="updateTime" column="update_time"/>
         <result property="deleted" column="deleted"/>
+        <result property="keywords" column="keywords"/>
+        <result property="sort" column="sort"/>
+        <result property="mid" column="mid"/>
     </resultMap>
 
     <resultMap id="TjSurveyQuestionTjSurveyOptionsResult" type="TjSurveyQuestion" extends="TjSurveyQuestionResult">
@@ -45,7 +48,10 @@
                create_time,
                update_by,
                update_time,
-               deleted
+               deleted,
+               keywords,
+               sort,
+               mid
         from tj_survey_question
     </sql>
 
@@ -64,7 +70,7 @@
         </where>
     </select>
 
-    <select id="selectTjSurveyQuestionByQid" parameterType="Long"
+    <select id="selectTjSurveyQuestionByQid" parameterType="String"
             resultMap="TjSurveyQuestionTjSurveyOptionsResult">
         select a.qid,
                a.question,
@@ -76,6 +82,8 @@
                a.update_by,
                a.update_time,
                a.deleted,
+               a.keywords,
+               a.sort,
                b.oid         as
                    sub_oid,
                b.qid         as
@@ -101,10 +109,103 @@
         where a.qid = #{qid}
     </select>
 
-    <insert id="insertTjSurveyQuestion" parameterType="TjSurveyQuestion" useGeneratedKeys="true"
-            keyProperty="qid">
+
+    <select id="getOptionsByMid" parameterType="String"
+            resultMap="TjSurveyQuestionTjSurveyOptionsResult">
+        select a.qid,
+               a.question,
+               a.type,
+               a.is_required,
+               a.remark,
+               a.create_by,
+               a.create_time,
+               a.update_by,
+               a.update_time,
+               a.deleted,
+               a.keywords,
+               a.sort,
+               b.oid         as
+                   sub_oid,
+               b.qid         as
+                   sub_qid,
+               b.ooption      as
+                   sub_ooption,
+               b.score       as
+                   sub_score,
+               b.remark      as
+                   sub_remark,
+               b.create_by   as
+                   sub_create_by,
+               b.create_time as
+                   sub_create_time,
+               b.update_by   as
+                   sub_update_by,
+               b.update_time as
+                   sub_update_time,
+               b.deleted     as
+                   sub_deleted
+        from tj_survey_question a
+                 left join tj_survey_options b on b.qid = a.qid
+        where a.mid = #{mid}
+    </select>
+
+
+    <select id="selectOptionsByQid" parameterType="String" resultType="TjSurveyOptions">
+        select oid,qid,ooption,score,remark,create_by,create_time,update_by,update_time,deleted from tj_survey_options
+        where qid = #{qid}
+    </select>
+
+<!--    <insert id="insertTjSurveyQuestion" parameterType="TjSurveyQuestion" useGeneratedKeys="true"-->
+<!--            keyProperty="qid">-->
+<!--        insert into tj_survey_question-->
+<!--        <trim prefix="(" suffix=")" suffixOverrides=",">-->
+<!--            <if test="question != null and question != ''">question,-->
+<!--            </if>-->
+<!--            <if test="type != null and type != ''">type,-->
+<!--            </if>-->
+<!--            <if test="isRequired != null and isRequired != ''">is_required,-->
+<!--            </if>-->
+<!--            <if test="remark != null">remark,-->
+<!--            </if>-->
+<!--            <if test="createBy != null">create_by,-->
+<!--            </if>-->
+<!--            <if test="createTime != null">create_time,-->
+<!--            </if>-->
+<!--            <if test="updateBy != null">update_by,-->
+<!--            </if>-->
+<!--            <if test="updateTime != null">update_time,-->
+<!--            </if>-->
+<!--            <if test="deleted != null">deleted,-->
+<!--            </if>-->
+<!--        </trim>-->
+<!--        <trim prefix="values (" suffix=")" suffixOverrides=",">-->
+<!--            <if test="question != null and question != ''">#{question},-->
+<!--            </if>-->
+<!--            <if test="type != null and type != ''">#{type},-->
+<!--            </if>-->
+<!--            <if test="isRequired != null and isRequired != ''">#{isRequired},-->
+<!--            </if>-->
+<!--            <if test="remark != null">#{remark},-->
+<!--            </if>-->
+<!--            <if test="createBy != null">#{createBy},-->
+<!--            </if>-->
+<!--            <if test="createTime != null">#{createTime},-->
+<!--            </if>-->
+<!--            <if test="updateBy != null">#{updateBy},-->
+<!--            </if>-->
+<!--            <if test="updateTime != null">#{updateTime},-->
+<!--            </if>-->
+<!--            <if test="deleted != null">#{deleted},-->
+<!--            </if>-->
+<!--        </trim>-->
+<!--    </insert>-->
+
+
+    <insert id="insertTjSurveyQuestion" parameterType="TjSurveyQuestion">
         insert into tj_survey_question
         <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="qid != null and qid != ''">qid,
+            </if>
             <if test="question != null and question != ''">question,
             </if>
             <if test="type != null and type != ''">type,
@@ -121,11 +222,18 @@
             </if>
             <if test="updateTime != null">update_time,
             </if>
-            <if test="deleted != null">deleted,
+            <if test="keywords != null">keywords,
             </if>
+            <if test="sort != null">sort,
+            </if>
+            <if test="mid != null">mid,
+            </if>
+
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
-            <if test="question != null and question != ''">#{question},
+            <if test="qid != null and qid != ''">#{qid},
+            </if>
+             <if test="question != null and question != ''">#{question},
             </if>
             <if test="type != null and type != ''">#{type},
             </if>
@@ -141,10 +249,14 @@
             </if>
             <if test="updateTime != null">#{updateTime},
             </if>
-            <if test="deleted != null">#{deleted},
+            <if test="keywords != null">#{keywords},
             </if>
+            <if test="sort != null">#{sort},</if>
+            <if test="mid != null">#{mid},</if>
+
         </trim>
     </insert>
+
 
     <update id="updateTjSurveyQuestion" parameterType="TjSurveyQuestion">
         update tj_survey_question
@@ -176,51 +288,132 @@
             <if test="deleted != null">deleted =
                 #{deleted},
             </if>
+            <if test="mid != null">mid =
+                #{mid},
+            </if>
+
+            <if test="keywords != null">keywords =
+                #{keywords},
+            </if>
+            <if test="sort != null">sort =
+                #{sort},
+            </if>
         </trim>
         where qid = #{qid}
     </update>
 
-    <delete id="deleteTjSurveyQuestionByQid" parameterType="Long">
-        delete
-        from tj_survey_question
-        where qid = #{qid}
-    </delete>
+    <update id="deleteTjSurveyQuestionByQid" parameterType="TjSurveyQuestion">
+        update tj_survey_question SET deleted = 1 where qid = #{qid}
+    </update>
 
-    <delete id="deleteTjSurveyQuestionByQids" parameterType="String">
-        delete from tj_survey_question where qid in
+
+    <update id="deleteTjSurveyQuestionByMid" parameterType="Long">
+        update tj_survey_question SET deleted = 1 where mid = #{mid}
+    </update>
+
+
+<!--    <delete id="deleteTjSurveyQuestionByQid" parameterType="String">-->
+<!--        delete-->
+<!--        from tj_survey_question-->
+<!--        where qid = #{qid}-->
+<!--    </delete>-->
+
+    <update id="deleteTjSurveyQuestionByQids" parameterType="Long">
+        update tj_survey_question set deleted=1 where mid in
+        <foreach item="mid" collection="array" open="(" separator="," close=")">
+            #{mid}
+        </foreach>
+    </update>
+
+    <update id="deleteTjSurveyOptionsByQids" parameterType="Long">
+        update tj_survey_options set deleted=1 where qid in
         <foreach item="qid" collection="array" open="(" separator="," close=")">
             #{qid}
         </foreach>
-    </delete>
+    </update>
 
-    <delete id="deleteTjSurveyOptionsByQids" parameterType="String">
-        delete from tj_survey_options where qid in
-        <foreach item="qid" collection="array" open="(" separator="," close=")">
-            #{qid}
-        </foreach>
-    </delete>
+<!--    <delete id="deleteTjSurveyQuestionByQids" parameterType="String">-->
+<!--        delete from tj_survey_question where qid in-->
+<!--        <foreach item="qid" collection="array" open="(" separator="," close=")">-->
+<!--            #{qid}-->
+<!--        </foreach>-->
+<!--    </delete>-->
 
-    <delete id="deleteTjSurveyOptionsByQid" parameterType="Long">
-        delete
-        from tj_survey_options
-        where qid = #{qid}
-    </delete>
+<!--    <delete id="deleteTjSurveyOptionsByQids" parameterType="String">-->
+<!--        delete from tj_survey_options where qid in-->
+<!--        <foreach item="qid" collection="array" open="(" separator="," close=")">-->
+<!--            #{qid}-->
+<!--        </foreach>-->
+<!--    </delete>-->
 
-    <insert id="batchTjSurveyOptions">
+<!--    <delete id="deleteTjSurveyOptionsByQid" parameterType="String">-->
+<!--        delete-->
+<!--        from tj_survey_options-->
+<!--        where qid = #{qid}-->
+<!--    </delete>-->
+
+    <update id="deleteTjSurveyOptionsByQid" parameterType="TjSurveyOptions">
+        update tj_survey_options SET deleted = 1 where qid = #{qid}
+    </update>
+
+
+
+    <insert id="insertTjSurveyOptions" parameterType="TjSurveyOptions">
         insert into tj_survey_options
-        ( oid , qid , ooption , score , remark , create_by , create_time , update_by , update_time , deleted) values
-        <foreach item="item" index="index" collection="list" separator=",">
-            ( #{item.oid
-                }, #{item.qid
-                }, #{item.ooption
-                }, #{item.score
-                }, #{item.remark
-                }, #{item.createBy
-                }, #{item.createTime
-                }, #{item.updateBy
-                }, #{item.updateTime
-                }, #{item.deleted
-                })
-        </foreach>
+        <trim prefix="(" suffix=")" suffixOverrides=",">
+            <if test="qid != null and qid != ''">qid,
+            </if>
+            <if test="ooption != null and ooption != ''">ooption,
+            </if>
+            <if test="score != null and score != ''">score,
+            </if>
+            <if test="remark != null">remark,
+            </if>
+            <if test="createBy != null">create_by,
+            </if>
+            <if test="createTime != null">create_time,
+            </if>
+            <if test="updateBy != null">update_by,
+            </if>
+            <if test="updateTime != null">update_time,
+            </if>
+        </trim>
+        <trim prefix="values (" suffix=")" suffixOverrides=",">
+            <if test="qid != null and qid != ''">#{qid},
+            </if>
+            <if test="ooption != null and ooption != ''">#{ooption},
+            </if>
+            <if test="score != null and score != ''">#{score},
+            </if>
+            <if test="remark != null">#{remark},
+            </if>
+            <if test="createBy != null">#{createBy},
+            </if>
+            <if test="createTime != null">#{createTime},
+            </if>
+            <if test="updateBy != null">#{updateBy},
+            </if>
+            <if test="updateTime != null">#{updateTime},
+            </if>
+
+        </trim>
     </insert>
+
+<!--    <insert id="batchTjSurveyOptions">-->
+<!--        insert into tj_survey_options-->
+<!--        ( oid , qid , ooption , score , remark , create_by , create_time , update_by , update_time , deleted) values-->
+<!--        <foreach item="item" index="index" collection="list" separator=",">-->
+<!--            ( #{item.oid-->
+<!--                }, #{item.qid-->
+<!--                }, #{item.ooption-->
+<!--                }, #{item.score-->
+<!--                }, #{item.remark-->
+<!--                }, #{item.createBy-->
+<!--                }, #{item.createTime-->
+<!--                }, #{item.updateBy-->
+<!--                }, #{item.updateTime-->
+<!--                }, #{item.deleted-->
+<!--                })-->
+<!--        </foreach>-->
+<!--    </insert>-->
 </mapper>
diff --git a/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyTemplateMapper.xml b/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyTemplateMapper.xml
index 8d9bdfe..fbe6e88 100644
--- a/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyTemplateMapper.xml
+++ b/ltkj-hosp/src/main/resources/mapper/hosp/TjSurveyTemplateMapper.xml
@@ -5,147 +5,223 @@
 <mapper namespace="com.ltkj.hosp.mapper.TjSurveyTemplateMapper">
 
     <resultMap type="TjSurveyTemplate" id="TjSurveyTemplateResult">
-            <result property="mid" column="mid"/>
-            <result property="tempName" column="temp_name"/>
-            <result property="tempType" column="temp_type"/>
-            <result property="remark" column="remark"/>
-            <result property="createBy" column="create_by"/>
-            <result property="createTime" column="create_time"/>
-            <result property="updateBy" column="update_by"/>
-            <result property="updateTime" column="update_time"/>
-            <result property="deleted" column="deleted"/>
+        <result property="mid" column="mid"/>
+        <result property="tempName" column="temp_name"/>
+        <result property="tempType" column="temp_type"/>
+        <result property="remark" column="remark"/>
+        <result property="createBy" column="create_by"/>
+        <result property="createTime" column="create_time"/>
+        <result property="updateBy" column="update_by"/>
+        <result property="updateTime" column="update_time"/>
+        <result property="deleted" column="deleted"/>
+        <result property="designId" column="design_id"/>
+        <result property="qybz" column="qybz"/>
     </resultMap>
 
-        <resultMap id="TjSurveyTemplateTjSurveyTempQuesResult" type="TjSurveyTemplate" extends="TjSurveyTemplateResult">
-            <collection property="tjSurveyTempQuesList" notNullColumn="sub_tqid"
-                        javaType="java.util.List" resultMap="TjSurveyTempQuesResult"/>
-        </resultMap>
+    <resultMap id="TjSurveyTemplateTjSurveyTempQuesResult" type="TjSurveyTemplate" extends="TjSurveyTemplateResult">
+        <collection property="tjSurveyTempQuesList" notNullColumn="sub_tqid"
+                    javaType="java.util.List" resultMap="TjSurveyTempQuesResult"/>
+    </resultMap>
 
-        <resultMap type="TjSurveyTempQues" id="TjSurveyTempQuesResult">
-                <result property="tqid" column="sub_tqid"/>
-                <result property="mid" column="sub_mid"/>
-                <result property="qid" column="sub_qid"/>
-                <result property="qname" column="sub_qname"/>
-                <result property="createBy" column="sub_create_by"/>
-                <result property="createTime" column="sub_create_time"/>
-                <result property="updateBy" column="sub_update_by"/>
-                <result property="updateTime" column="sub_update_time"/>
-                <result property="deleted" column="sub_deleted"/>
-        </resultMap>
+    <resultMap type="TjSurveyTempQues" id="TjSurveyTempQuesResult">
+        <result property="tqid" column="sub_tqid"/>
+        <result property="mid" column="sub_mid"/>
+        <result property="qid" column="sub_qid"/>
+        <result property="qname" column="sub_qname"/>
+        <result property="createBy" column="sub_create_by"/>
+        <result property="createTime" column="sub_create_time"/>
+        <result property="updateBy" column="sub_update_by"/>
+        <result property="updateTime" column="sub_update_time"/>
+        <result property="deleted" column="sub_deleted"/>
+    </resultMap>
 
     <sql id="selectTjSurveyTemplateVo">
-        select mid, temp_name, temp_type, remark, create_by, create_time, update_by, update_time, deleted
+        select mid,
+               temp_name,
+               temp_type,
+               remark,
+               create_by,
+               create_time,
+               update_by,
+               update_time,
+               deleted,
+               qybz,
+               design_id
         from tj_survey_template
     </sql>
 
     <select id="selectTjSurveyTemplateList" parameterType="TjSurveyTemplate" resultMap="TjSurveyTemplateResult">
         <include refid="selectTjSurveyTemplateVo"/>
         <where>
-                        <if test="tempName != null  and tempName != ''">
-                            and temp_name like concat('%', #{tempName}, '%')
-                        </if>
-                        <if test="tempType != null  and tempType != ''">
-                            and temp_type = #{tempType}
-                        </if>
-                        <if test="deleted != null ">
-                            and deleted = #{deleted}
-                        </if>
+            <if test="tempName != null  and tempName != ''">
+                and temp_name like concat('%', #{tempName}, '%')
+            </if>
+            <if test="tempType != null  and tempType != ''">
+                and temp_type = #{tempType}
+            </if>
+            <if test="deleted != null ">
+                and deleted = #{deleted}
+            </if>
         </where>
     </select>
 
     <select id="selectTjSurveyTemplateByMid" parameterType="Long"
             resultMap="TjSurveyTemplateTjSurveyTempQuesResult">
-            select a.mid, a.temp_name, a.temp_type, a.remark, a.create_by, a.create_time, a.update_by, a.update_time, a.deleted,
- b.tqid as
-                sub_tqid, b.mid as
-                sub_mid, b.qid as
-                sub_qid, b.qname as
-                sub_qname, b.create_by as
-                sub_create_by, b.create_time as
-                sub_create_time, b.update_by as
-                sub_update_by, b.update_time as
-                sub_update_time, b.deleted as
-                sub_deleted
-            from tj_survey_template a
-            left join tj_survey_temp_ques b on b.mid = a.mid
-            where a.mid = #{mid}
+        select a.mid,
+               a.temp_name,
+               a.temp_type,
+               a.remark,
+               a.create_by,
+               a.create_time,
+               a.update_by,
+               a.update_time,
+               a.deleted,
+               a.design_id,
+               a.qybz,
+               b.tqid        as
+                   sub_tqid,
+               b.mid         as
+                   sub_mid,
+               b.qid         as
+                   sub_qid,
+               b.qname       as
+                   sub_qname,
+               b.create_by   as
+                   sub_create_by,
+               b.create_time as
+                   sub_create_time,
+               b.update_by   as
+                   sub_update_by,
+               b.update_time as
+                   sub_update_time,
+               b.deleted     as
+                   sub_deleted
+        from tj_survey_template a
+                 left join tj_survey_temp_ques b on b.mid = a.mid
+        where a.mid = #{mid}
+    </select>
+
+    <update id="qybzTjSurveyTemplateByQy" parameterType="Long">
+        update tj_survey_template
+        set qybz=0
+        where mid = #{mid}
+    </update>
+
+    <update id="qybzTjSurveyTemplateByJy" parameterType="Long">
+        update tj_survey_template
+        set qybz=1
+        where mid = #{mid}
+    </update>
+
+
+    <select id="selectTemplateByMid1" parameterType="Long"
+            resultType="TjSurveyTemplate">
+        select mid,
+               temp_name,
+               temp_type,
+               remark,
+               create_by,
+               create_time,
+               update_by,
+               update_time,
+               deleted,
+               qybz,
+               design_id
+        from tj_survey_template
+        where mid = #{mid}
+          AND deleted = 0
     </select>
 
     <insert id="insertTjSurveyTemplate" parameterType="TjSurveyTemplate" useGeneratedKeys="true"
             keyProperty="mid">
         insert into tj_survey_template
         <trim prefix="(" suffix=")" suffixOverrides=",">
-                    <if test="tempName != null">temp_name,
-                    </if>
-                    <if test="tempType != null">temp_type,
-                    </if>
-                    <if test="remark != null">remark,
-                    </if>
-                    <if test="createBy != null">create_by,
-                    </if>
-                    <if test="createTime != null">create_time,
-                    </if>
-                    <if test="updateBy != null">update_by,
-                    </if>
-                    <if test="updateTime != null">update_time,
-                    </if>
-                    <if test="deleted != null">deleted,
-                    </if>
+            <if test="tempName != null">temp_name,
+            </if>
+            <if test="tempType != null">temp_type,
+            </if>
+            <if test="remark != null">remark,
+            </if>
+            <if test="createBy != null">create_by,
+            </if>
+            <if test="createTime != null">create_time,
+            </if>
+            <if test="updateBy != null">update_by,
+            </if>
+            <if test="updateTime != null">update_time,
+            </if>
+            <if test="deleted != null">deleted,
+            </if>
+            <if test="designId != null">design_id,
+            </if>
+            <if test="qybz != null">qybz,
+            </if>
         </trim>
         <trim prefix="values (" suffix=")" suffixOverrides=",">
-                    <if test="tempName != null">#{tempName},
-                    </if>
-                    <if test="tempType != null">#{tempType},
-                    </if>
-                    <if test="remark != null">#{remark},
-                    </if>
-                    <if test="createBy != null">#{createBy},
-                    </if>
-                    <if test="createTime != null">#{createTime},
-                    </if>
-                    <if test="updateBy != null">#{updateBy},
-                    </if>
-                    <if test="updateTime != null">#{updateTime},
-                    </if>
-                    <if test="deleted != null">#{deleted},
-                    </if>
+            <if test="tempName != null">#{tempName},
+            </if>
+            <if test="tempType != null">#{tempType},
+            </if>
+            <if test="remark != null">#{remark},
+            </if>
+            <if test="createBy != null">#{createBy},
+            </if>
+            <if test="createTime != null">#{createTime},
+            </if>
+            <if test="updateBy != null">#{updateBy},
+            </if>
+            <if test="updateTime != null">#{updateTime},
+            </if>
+            <if test="deleted != null">#{deleted},
+            </if>
+            <if test="designId != null">#{designId},
+            </if>
+            <if test="qybz != null">#{qybz},
+            </if>
         </trim>
     </insert>
 
     <update id="updateTjSurveyTemplate" parameterType="TjSurveyTemplate">
         update tj_survey_template
         <trim prefix="SET" suffixOverrides=",">
-                    <if test="tempName != null">temp_name =
-                        #{tempName},
-                    </if>
-                    <if test="tempType != null">temp_type =
-                        #{tempType},
-                    </if>
-                    <if test="remark != null">remark =
-                        #{remark},
-                    </if>
-                    <if test="createBy != null">create_by =
-                        #{createBy},
-                    </if>
-                    <if test="createTime != null">create_time =
-                        #{createTime},
-                    </if>
-                    <if test="updateBy != null">update_by =
-                        #{updateBy},
-                    </if>
-                    <if test="updateTime != null">update_time =
-                        #{updateTime},
-                    </if>
-                    <if test="deleted != null">deleted =
-                        #{deleted},
-                    </if>
+            <if test="tempName != null">temp_name =
+                #{tempName},
+            </if>
+            <if test="tempType != null">temp_type =
+                #{tempType},
+            </if>
+            <if test="remark != null">remark =
+                #{remark},
+            </if>
+            <if test="createBy != null">create_by =
+                #{createBy},
+            </if>
+            <if test="createTime != null">create_time =
+                #{createTime},
+            </if>
+            <if test="updateBy != null">update_by =
+                #{updateBy},
+            </if>
+            <if test="updateTime != null">update_time =
+                #{updateTime},
+            </if>
+            <if test="deleted != null">deleted =
+                #{deleted},
+            </if>
+            <if test="designId != null">design_id =
+                #{designId},
+            </if>
+            <if test="qybz != null">qybz =
+                #{qybz},
+            </if>
         </trim>
         where mid = #{mid}
     </update>
 
     <delete id="deleteTjSurveyTemplateByMid" parameterType="Long">
         delete
-        from tj_survey_template where mid = #{mid}
+        from tj_survey_template
+        where mid = #{mid}
     </delete>
 
     <delete id="deleteTjSurveyTemplateByMids" parameterType="String">
@@ -155,23 +231,24 @@
         </foreach>
     </delete>
 
-        <delete id="deleteTjSurveyTempQuesByMids" parameterType="String">
-            delete from tj_survey_temp_ques where mid in
-            <foreach item="mid" collection="array" open="(" separator="," close=")">
-                #{mid}
-            </foreach>
-        </delete>
+    <delete id="deleteTjSurveyTempQuesByMids" parameterType="String">
+        delete from tj_survey_temp_ques where mid in
+        <foreach item="mid" collection="array" open="(" separator="," close=")">
+            #{mid}
+        </foreach>
+    </delete>
 
-        <delete id="deleteTjSurveyTempQuesByMid" parameterType="Long">
-            delete
-            from tj_survey_temp_ques where mid = #{mid}
-        </delete>
+    <delete id="deleteTjSurveyTempQuesByMid" parameterType="Long">
+        delete
+        from tj_survey_temp_ques
+        where mid = #{mid}
+    </delete>
 
-        <insert id="batchTjSurveyTempQues">
-            insert into tj_survey_temp_ques
-            ( tqid            , mid            , qid            , qname            , create_by            , create_time            , update_by            , update_time            , deleted) values
-            <foreach item="item" index="index" collection="list" separator=",">
-                ( #{item.tqid
+    <insert id="batchTjSurveyTempQues">
+        insert into tj_survey_temp_ques
+        ( tqid , mid , qid , qname , create_by , create_time , update_by , update_time , deleted) values
+        <foreach item="item" index="index" collection="list" separator=",">
+            ( #{item.tqid
                 }, #{item.mid
                 }, #{item.qid
                 }, #{item.qname
@@ -181,6 +258,8 @@
                 }, #{item.updateTime
                 }, #{item.deleted
                 })
-            </foreach>
-        </insert>
-</mapper>
\ No newline at end of file
+        </foreach>
+    </insert>
+
+
+</mapper>
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/constant/CommonConstants.java b/ltkj-system/src/main/java/com/ltkj/tduck/constant/CommonConstants.java
new file mode 100644
index 0000000..7ca1759
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/constant/CommonConstants.java
@@ -0,0 +1,96 @@
+package com.ltkj.tduck.constant;
+
+/**
+ * @description: 閫氱敤鐨勫父浜�
+ * @author: smalljop
+ * @create: 2018-09-27 13:25
+ **/
+public interface CommonConstants {
+
+
+    /**
+     * 瓒呯骇绠$悊鍛榠d
+     */
+    Long SUPER_ADMIN_ID = 1L;
+
+
+    String USER_KEY = "userId";
+    /**
+     * 鐢ㄦ埛姝e父鐘舵��
+     * 1:姝e父 0 :绂佺敤
+     */
+    Integer USER_NORMAL_STATUS = 1;
+    /**
+     * 鏂囦欢涓嬭浇content_type
+     */
+    String FILE_DOWNLOAD_CONTENT_TYPE = "application/octet-stream;charset=UTF-8";
+
+
+    /**
+     * 鏁板瓧甯搁噺
+     */
+    interface ConstantNumber {
+        /**
+         * @Fields NEGATIVE : ( -1 )
+         */
+        Integer NEGATIVE = -1;
+
+        /**
+         * @Fields ZERO : ( 0 )
+         */
+        Integer ZERO = 0;
+
+        /**
+         * @Fields ONE : ( 1 )
+         */
+        Integer ONE = 1;
+
+        /**
+         * @Fields TOW : ( 2 )
+         */
+        Integer TOW = 2;
+
+        /**
+         * @Fields THREE : ( 3 )
+         */
+        Integer THREE = 3;
+
+        /**
+         * @Fields FOUR : ( 4 )
+         */
+        Integer FOUR = 4;
+
+        /**
+         * @Fields FIVE : ( 5 )
+         */
+        Integer FIVE = 5;
+
+        /**
+         * @Fields FIVE : ( 6 )
+         */
+        Integer SIX = 6;
+
+        /**
+         * @Fields FIVE : ( 7 )
+         */
+        Integer Seven = 7;
+
+        /**
+         * @Fields FIVE : ( 8 )
+         */
+        Integer Eight = 8;
+
+        /**
+         * @Fields FIVE : ( 9 )
+         */
+        Integer Nine = 9;
+
+        /**
+         * @Fields FIVE : ( 10 )
+         */
+        Integer Ten = 10;
+
+
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormConstants.java b/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormConstants.java
new file mode 100644
index 0000000..06867b8
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormConstants.java
@@ -0,0 +1,35 @@
+package com.ltkj.tduck.constant;
+
+/**
+ * @author : smalljop
+ * @description :
+ * @create : 2020-11-11 18:16
+ **/
+public interface FormConstants {
+
+    /**
+     * 閫夋嫨鎬х粍浠朵繚瀛樹細鍒涘缓涓や釜瀛楁 涓�涓瓨鏀綢d 涓�涓瓨鏀鹃�夐」鍚�
+     */
+    String FIELD_SUFFIX_LABEL = "label";
+
+
+    /**
+     * 琛ㄥ崟Item鎺掑簭浣嶇疆鑷
+     */
+    String FORM_ITEM_POS_DELTA = "form:item:pos:{}";
+
+
+    /**
+     * 鎵嬫満鍙烽獙璇佺爜
+     */
+    String PHONE_NUMBER_CODE = "form:mobile:code:{}";
+
+
+    /**
+     * 鏌ョ湅琛ㄥ崟鏁�
+     */
+    String FORM_VIEW_COUNT = "form:view:count:{}";
+
+    String FORM_RESULT_NUMBER = "form:view:result:{}";
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormRedisKeyConstants.java b/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormRedisKeyConstants.java
new file mode 100644
index 0000000..5f6d1e1
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormRedisKeyConstants.java
@@ -0,0 +1,66 @@
+package com.ltkj.tduck.constant;
+
+/**
+ * @description: redis key甯搁噺
+ **/
+public interface FormRedisKeyConstants {
+    /**
+     * 琛ㄥ崟Item鎺掑簭浣嶇疆鑷
+     */
+    String FORM_ITEM_POS_DELTA = "form:item:pos:{}";
+
+
+    /**
+     * 鎵嬫満鍙烽獙璇佺爜
+     */
+    String PHONE_NUMBER_CODE = "form:mobile:code:{}";
+    /**
+     * 琛ㄥ崟Item鎺掑簭浣嶇疆鑷
+     */
+    String FORM_RESULT_NUMBER = "form:result:number:{}";
+
+    /**
+     * 鏌ョ湅琛ㄥ崟IP璁板綍鍒楄〃
+     */
+    String FORM_VIEW_IP_LIST = "form:view:ip:list:{}";
+
+    /**
+     * 琛ㄥ崟鏌ョ湅娆℃暟
+     */
+    String FORM_VIEW_COUNT_KEY = "form:view:count:{}";
+
+    /**
+     * 琛ㄥ崟棰勭害浜烘暟
+     */
+    String FORM_RESERVE_COUNT = "form:reserve:count:{}:{}:{}";
+
+    /**
+     * 鍟嗗搧鍗栧嚭鏁伴噺
+     */
+    String FORM_GOODS_SELL_QUANTITY = "form:goods:sell:quantity:{}:{}";
+
+    /**
+     * 鍟嗗搧鏄惁鏀粯鐘舵��
+     */
+    String FORM_GOODS_PAY_STATUS = "form:goods:pay:status:{}";
+
+    /**
+     * 鍟嗗搧寰呮彁浜よ〃鍗曟暟鎹�
+     */
+    String FORM_GOODS_SUBMIT_DATA = "form:goods:submit:data:{}";
+
+    /**
+     * 鍟嗗搧鏀粯閲戦
+     */
+    String FORM_GOODS_PAY_PRICE = "form:goods:pay:price:{}";
+
+    /**
+     * 琛ㄥ崟鎶曠エ鏁伴噺 {formKey}:{formItemId}
+     */
+    String FORM_VOTE_COUNT = "form:vote:count:{}:{}";
+
+    /**
+     * 琛ㄥ崟鍗曢�夊悕棰� {formKey}:{formItemId}
+     */
+    String FORM_OPTION_QUANTITY = "form:option:count:{}:{}";
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormSettingConstants.java b/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormSettingConstants.java
new file mode 100644
index 0000000..b0925db
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/constant/FormSettingConstants.java
@@ -0,0 +1,21 @@
+package com.ltkj.tduck.constant;
+
+/**
+ * @author : wangqing
+ * @description : 琛ㄥ崟璁剧疆椤瑰父閲�
+ * @create :  2022/07/07 11:49
+ **/
+public interface FormSettingConstants {
+
+    /**
+     * 琛ㄥ崟鎻愪氦鍚庢樉绀虹被鍨嬪瓧娈靛悕绉�
+     */
+    String SUBMIT_SHOW_TYPE_KEY = "submitShowType";
+
+    /**
+     * 鑷畾涔夋彁绀洪〉闈㈠唴瀹�
+     */
+    String SUBMIT_SHOW_CUSTOM_PAGE_KEY = "submitShowCustomPage";
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/constant/ResponseCodeConstants.java b/ltkj-system/src/main/java/com/ltkj/tduck/constant/ResponseCodeConstants.java
new file mode 100644
index 0000000..e7e6819
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/constant/ResponseCodeConstants.java
@@ -0,0 +1,45 @@
+package com.ltkj.tduck.constant;
+
+/**
+ * @description: 鍝嶅簲鐘舵�佺爜
+ * @author: smalljop
+ * @create: 2020-02-10 15:46
+ **/
+public interface ResponseCodeConstants {
+    /**
+     * 鎺ュ彛鎴愬姛
+     */
+    int SUCCESS = 200;
+    /**
+     * 鎺ュ彛澶辫触 鍙戠敓寮傚父
+     */
+    int FAIL = 500;
+
+    /**
+     * 鏈櫥褰�
+     */
+    int UNAUTHORIZED = 401;
+
+    /**
+     * 闇�瑕侀獙璇佺殑璇锋眰
+     */
+    int NEED_VERIFICATION = 416;
+
+    /**
+     * 鎵句笉鍒拌璇锋眰
+     */
+    int NOT_FOUND = 404;
+
+    /**
+     * 闈炴硶绛惧悕
+     */
+    Integer SIGN_FAIL_CODE = 405;
+
+    /**
+     * 闈炴硶绛惧悕
+     */
+    String SIGN_FAIL_MSG = "闈炴硶璁块棶锛岃妫�鏌ヨ姹備俊鎭�";
+
+
+    String VALIDATE_CODE_FAIL_MSG = "楠岃瘉鐮侀獙璇佸け璐�";
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/FormTemplateCategoryEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/FormTemplateCategoryEntity.java
new file mode 100644
index 0000000..d827174
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/FormTemplateCategoryEntity.java
@@ -0,0 +1,26 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+
+
+/**
+ * 琛ㄥ崟涓婚鍒嗙被
+ *
+ * @author smalljop
+ * @since 2021-01-06 10:50:51
+ */
+
+@Data
+@TableName(value = "fm_form_template_category", autoResultMap = true)
+public class FormTemplateCategoryEntity {
+    /**
+     * 涓婚鍚嶇О
+     */
+    private String name;
+    /**
+     * 鎺掑簭
+     */
+    private Integer sort;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/FormThemeEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/FormThemeEntity.java
new file mode 100644
index 0000000..1d53a16
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/FormThemeEntity.java
@@ -0,0 +1,44 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableName;
+import lombok.Data;
+import lombok.experimental.FieldNameConstants;
+
+
+/**
+ * 琛ㄥ崟涓婚澶栬妯℃澘(FormTheme)琛ㄥ疄浣撶被
+ *
+ * @author smalljop
+ * @since 2020-11-23 18:33:50
+ */
+@Data
+@TableName(value = "fm_form_theme", autoResultMap = true)
+@FieldNameConstants
+public class FormThemeEntity {
+
+    /**
+     * 涓婚鍚嶇О
+     */
+    private String name;
+    /**
+     * 涓婚椋庢牸
+     */
+    private Long style;
+    /**
+     * 澶撮儴鍥剧墖
+     */
+    private String headImgUrl;
+
+    /**
+     * 鑳屾櫙鍥剧墖
+     */
+    private String backgroundImg;
+
+
+    /**
+     * 涓婚棰滆壊
+     */
+    private String themeColor;
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/PageRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/PageRequest.java
new file mode 100644
index 0000000..95f2034
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/PageRequest.java
@@ -0,0 +1,21 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.Data;
+
+/**
+ * @author : smalljop
+ * @description : 鍒嗛〉
+ * @create : 2020-12-09 10:47
+ **/
+@Data
+public class PageRequest {
+
+    private long current = 1;
+    private long size = 50;
+
+
+    public Page toMybatisPage() {
+        return new Page(current, size);
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/SysBaseEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/SysBaseEntity.java
new file mode 100644
index 0000000..c08e573
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/SysBaseEntity.java
@@ -0,0 +1,50 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Data;
+import lombok.experimental.FieldNameConstants;
+
+import java.io.Serializable;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Entity鍩虹被
+ *
+ * @author smalljop
+ */
+@Data
+@FieldNameConstants
+public class SysBaseEntity extends TBaseEntity implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * 鎼滅储鍊�
+     */
+    @TableField(exist = false)
+    private String searchValue;
+
+    /**
+     * 鍒涘缓鑰�
+     */
+    private String createBy;
+
+    /**
+     * 鏇存柊鑰�
+     */
+    private String updateBy;
+
+
+    /**
+     * 璇锋眰鍙傛暟
+     */
+    @TableField(exist = false)
+    private Map<String, Object> params;
+
+    public Map<String, Object> getParams() {
+        if (params == null) {
+            params = new HashMap<>();
+        }
+        return params;
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/TBaseEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/TBaseEntity.java
new file mode 100644
index 0000000..5736860
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/TBaseEntity.java
@@ -0,0 +1,57 @@
+package com.ltkj.tduck.domain;
+
+import cn.hutool.core.date.DatePattern;
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.extension.activerecord.Model;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
+import com.fasterxml.jackson.databind.annotation.JsonSerialize;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.ltkj.tduck.utils.LongToStringSerializer;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.experimental.FieldNameConstants;
+
+import java.time.LocalDateTime;
+import java.util.Date;
+
+/**
+ * @description: 瀹炰綋绫诲熀绫�
+ * @author: smalljop
+ * @create: 2020-02-15 22:57
+ **/
+@Data
+@FieldNameConstants
+@EqualsAndHashCode(callSuper = false)
+public class TBaseEntity<T> extends Model {
+
+    private static final long serialVersionUID = 1L;
+
+
+    /**
+     * 涓婚敭 閬垮厤瓒呭嚭闀垮害 鍓嶇涓㈠け绮惧害
+     */
+    @JsonSerialize(using= LongToStringSerializer.class)
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     **/
+    @TableField(fill = FieldFill.INSERT)
+//    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+//    @JsonSerialize(using = LocalDateTimeSerializer.class)
+    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+    protected Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     **/
+    @TableField(fill = FieldFill.INSERT_UPDATE)
+    @JsonFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+//    @JsonDeserialize(using = LocalDateTimeDeserializer.class)
+//    @JsonSerialize(using = LocalDateTimeSerializer.class)
+    protected Date updateTime;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormDataEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormDataEntity.java
new file mode 100644
index 0000000..930be59
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormDataEntity.java
@@ -0,0 +1,112 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldFill;
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonFormat;
+import com.ltkj.common.annotation.Excel;
+import com.ltkj.tduck.enums.FormTypeEnum;
+import com.ltkj.tduck.handler.JacksonTypeHandler;
+import io.swagger.annotations.ApiModelProperty;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import lombok.experimental.FieldNameConstants;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Date;
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟鏁版嵁(FormResult)琛ㄥ疄浣撶被
+ *
+ * @author smalljop
+ * @since 2020-11-23 14:09:20
+ */
+@Data
+@Accessors(chain = true)
+@FieldNameConstants
+@TableName(value = "fm_user_form_data", autoResultMap = true)
+public class UserFormDataEntity extends SysBaseEntity {
+
+    /**
+     * 琛ㄥ崟key
+     */
+    @NotBlank(message = "閿欒璇锋眰")
+    private String formKey;
+
+
+    /**
+     * 鎻愪氦搴忓彿
+     */
+    private Long serialNumber;
+
+    /**
+     * 濉啓缁撴灉鍘熷鏁版嵁
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Map<String, Object> originalData;
+
+
+    @TableField(exist = false)
+    private FormTypeEnum formType;
+
+    /**
+     * 濉啓鐢ㄦ埛Ua
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Map<String, Object> submitUa;
+
+    /**
+     * 鎻愪氦绯荤粺
+     */
+    private String submitOs;
+
+
+    /**
+     * 鎻愪氦娴忚鍣�
+     */
+    private String submitBrowser;
+
+    /**
+     * 鎻愪氦ip
+     */
+    private String submitRequestIp;
+
+
+    /**
+     * 鎻愪氦ip
+     */
+    private String submitAddress;
+
+    /**
+     * 瀹屾垚鏃堕棿
+     */
+    private Long completeTime;
+
+    /**
+     * 寰俊openID
+     */
+    private String wxOpenId;
+
+    /**
+     * 寰俊鐢ㄦ埛淇℃伅
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Map<String, Object> wxUserInfo;
+
+    /**
+     * 鎵╁睍瀛楁
+     */
+    private String extValue;
+
+
+    /**
+     * 浣撴鍙�
+     */
+    private String tjNumber;
+
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormEntity.java
new file mode 100644
index 0000000..90f6616
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormEntity.java
@@ -0,0 +1,104 @@
+package com.ltkj.tduck.domain;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ltkj.tduck.enums.FormSourceTypeEnum;
+import com.ltkj.tduck.enums.FormStatusEnum;
+import com.ltkj.tduck.utils.HtmlUtils;
+import lombok.Data;
+import lombok.experimental.FieldNameConstants;
+import org.apache.ibatis.type.BooleanTypeHandler;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Date;
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟琛�(Form)琛ㄥ疄浣撶被
+ */
+@Data
+@FieldNameConstants
+@TableName(value = "fm_user_form", autoResultMap = true)
+public class UserFormEntity{
+
+    /**
+     * 涓婚敭 閬垮厤瓒呭嚭闀垮害 鍓嶇涓㈠け绮惧害
+     */
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     **/
+    protected Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     **/
+    protected Date updateTime;
+
+    /**
+     * 琛ㄥ崟code
+     */
+    @NotBlank(message = "閿欒璇锋眰")
+    private String formKey;
+    /**
+     * 琛ㄥ崟鍚嶇О
+     */
+    @NotBlank(message = "琛ㄥ崟鍚嶇О涓嶈兘涓虹┖")
+    private String name;
+    /**
+     * 琛ㄥ崟鎻忚堪
+     */
+    private String description;
+
+
+    /**
+     * 琛ㄥ崟鏉ユ簮
+     */
+    private Integer sourceType;
+
+    /**
+     * 鏉ユ簮ID
+     */
+    private String sourceId;
+
+    /**
+     * 鐢ㄦ埛ID
+     */
+    private Long userId;
+
+    /***
+     * 鐘舵��
+     */
+    private Integer status;
+    /**
+     * 琛ㄥ崟绫诲瀷
+     */
+    private String type;
+
+    @TableField(value = "is_deleted", typeHandler = BooleanTypeHandler.class)
+    private Boolean deleted;
+
+    /**
+     * 鏄惁鏄枃浠跺す
+     */
+    @TableField(value = "is_folder", typeHandler = BooleanTypeHandler.class)
+    private Boolean folder;
+    /**
+     * 鐖剁骇鏂囦欢澶笽D
+     */
+    private Long folderId;
+
+
+    /**
+     * 绉婚櫎html鏍囩
+     * @return 鏂囨湰
+     */
+    public String getTextName() {
+        if (StrUtil.isBlank(name)) {
+            return null;
+        }
+        // 鏍囬鏄瘜鏂囨湰 鍘婚櫎html 鏍囩
+        return HtmlUtils.cleanHtmlTag(name);
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormItemEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormItemEntity.java
new file mode 100644
index 0000000..ae82fa0
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormItemEntity.java
@@ -0,0 +1,145 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.FieldStrategy;
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import com.ltkj.tduck.enums.FormItemTypeEnum;
+import com.ltkj.tduck.utils.HtmlUtils;
+import lombok.Data;
+import lombok.experimental.Accessors;
+import lombok.experimental.FieldNameConstants;
+import org.apache.ibatis.type.BooleanTypeHandler;
+import org.apache.ibatis.type.EnumTypeHandler;
+
+import javax.validation.constraints.NotNull;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(FormItem)琛ㄥ疄浣撶被
+ *
+ * @author smalljop
+ * @since 2020-11-19 10:49:16
+ */
+@Data
+@Accessors(chain = true)
+@FieldNameConstants
+@JsonIgnoreProperties(ignoreUnknown = true)
+@TableName(value = "fm_user_form_item", autoResultMap = true)
+public class UserFormItemEntity {
+
+    /**
+     * 涓婚敭 閬垮厤瓒呭嚭闀垮害 鍓嶇涓㈠け绮惧害
+     */
+    private Long id;
+
+    /**
+     * 鍒涘缓鏃堕棿
+     **/
+    protected Date createTime;
+
+    /**
+     * 鏇存柊鏃堕棿
+     **/
+    protected Date updateTime;
+
+
+    /**
+     * 琛ㄥ崟Id
+     */
+    @NotNull(message = "key璇锋眰寮傚父")
+    private String formKey;
+    /**
+     * 琛ㄥ崟椤笽d 绫诲瀷  + 鏃堕棿鎴�
+     */
+    @NotNull(message = "Id璇锋眰閿欒")
+    private String formItemId;
+    /**
+     * 琛ㄥ崟椤圭被鍨�
+     */
+    @NotNull(message = "绫诲瀷璇锋眰閿欒")
+    @TableField(typeHandler = EnumTypeHandler.class)
+    private FormItemTypeEnum type;
+    /**
+     * 琛ㄥ崟椤规爣棰�
+     */
+    @NotNull(message = "鏍囬涓嶈兘涓虹┖")
+    private String label;
+
+
+    /**
+     * 灞曠ず绫诲瀷缁勪欢 鍙湪琛ㄥ崟濉啓椤垫煡璇㈠埌
+     */
+    @TableField(value = "is_display_type", typeHandler = BooleanTypeHandler.class)
+    private Boolean displayType;
+
+    /**
+     * 闅愯棌绫诲瀷缁勪欢 鍦ㄨ〃鍗曞~鍐欓〉闈㈡棤娉曟煡鐪嬪埌
+     */
+    @TableField(value = "is_hide_type", typeHandler = BooleanTypeHandler.class)
+    private Boolean hideType;
+
+    /**
+     * 闇�瑕佸湪鍏ュ簱鍓嶇壒娈婂鐞嗙殑缁勪欢 姣斿闅忔満缂栫爜绛� 楠岄噸
+     */
+    @TableField(value = "is_special_type", typeHandler = BooleanTypeHandler.class)
+    private Boolean specialType;
+    /**
+     * 鏄惁鏄剧ず鏍囩
+     */
+    @TableField(typeHandler = BooleanTypeHandler.class)
+    private Boolean showLabel;
+
+    /**
+     * 琛ㄥ崟椤归粯璁ゅ��
+     */
+    @TableField(updateStrategy = FieldStrategy.IGNORED)
+    private String defaultValue;
+
+
+    /**
+     * 鏄惁蹇呭~
+     */
+    @TableField(typeHandler = BooleanTypeHandler.class)
+    private Boolean required;
+    /**
+     * 杈撳叆鍨嬫彁绀烘枃瀛�
+     */
+    private String placeholder;
+    /**
+     * 鎺掑簭
+     */
+    private Long sort;
+
+    /**
+     * 鏍呮牸瀹藉害
+     */
+    private int span;
+
+    /**
+     * 鎵╁睍瀛楁 琛ㄥ崟椤圭嫭鏈夊瓧娈�
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Map<String, Object> scheme;
+
+    /**
+     * 姝e垯琛ㄨ揪寮�
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<Map<String, Object>> regList;
+
+
+    /**
+     * 鍘婚櫎html鏍煎紡
+     *
+     * @return
+     */
+    public String getTextLabel() {
+        return HtmlUtils.cleanHtmlTag(this.label);
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormLogicEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormLogicEntity.java
new file mode 100644
index 0000000..d67ba99
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormLogicEntity.java
@@ -0,0 +1,88 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import lombok.Data;
+import lombok.experimental.Accessors;
+
+import javax.validation.constraints.NotBlank;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * 琛ㄥ崟閫昏緫(UserFormLogic)琛ㄥ疄浣撶被
+ *
+ * @author smalljop
+ * @since 2020-05-01 13:36:27
+ */
+@Data
+@Accessors(chain = true)
+@TableName(value = "fm_user_form_logic", autoResultMap = true)
+public class UserFormLogicEntity {
+    /**
+     * 琛ㄥ崟key
+     */
+    @NotBlank(message = "formKey涓嶈兘涓虹┖")
+    private String formKey;
+
+
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private List<Definition> scheme;
+
+    /**
+     * 閫昏緫瀹氫箟瀵硅薄
+     */
+    @Data
+    public static class Definition {
+
+        /**
+         * 瑙﹀彂鍐呭
+         */
+        private Set<Trigger> triggerList;
+        /**
+         * 鏉′欢
+         */
+        private Set<Condition> conditionList;
+    }
+
+
+    @Data
+    public static class Trigger {
+        /**
+         * 琛ㄥ崟椤笽d
+         */
+        private String formItemId;
+        /**
+         * 绫诲瀷
+         */
+        private String type = "show";
+    }
+
+    /**
+     * 鏉′欢
+     */
+    @Data
+    public static class Condition {
+        /**
+         * 琛ㄥ崟椤笽d
+         */
+        private String formItemId;
+        /**
+         * 琛ㄨ揪寮�
+         */
+        private String expression;
+        /**
+         * 閫夐」
+         */
+        private Object optionValue;
+
+
+        /**
+         * AND OR
+         */
+        private String relation;
+
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormSettingEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormSettingEntity.java
new file mode 100644
index 0000000..3cf723e
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormSettingEntity.java
@@ -0,0 +1,36 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ltkj.common.core.domain.BaseEntity;
+import com.ltkj.tduck.handler.JacksonTypeHandler;
+import lombok.Data;
+import lombok.experimental.FieldNameConstants;
+
+import javax.validation.constraints.NotBlank;
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟璁剧疆瀵硅薄
+ *
+ * @author tduck
+ * @date 2021-08-12 16:19:57
+ */
+@Data
+@FieldNameConstants
+@TableName(value = "fm_user_form_setting", autoResultMap = true)
+public class UserFormSettingEntity extends BaseEntity {
+
+
+    @NotBlank
+    private String formKey;
+
+
+    /**
+     * 璁剧疆鍏蜂綋鍐呭
+     */
+    @TableField(typeHandler = JacksonTypeHandler.class)
+    private Map<String, Object> settings;
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormThemeEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormThemeEntity.java
new file mode 100644
index 0000000..f3c9191
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormThemeEntity.java
@@ -0,0 +1,86 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.Data;
+import org.apache.ibatis.type.BooleanTypeHandler;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(UserFormTheme)琛ㄥ疄浣撶被
+ *
+ * @author smalljop
+ * @since 2020-11-25 13:36:27
+ */
+@Data
+@JsonIgnoreProperties(ignoreUnknown = true)
+@TableName(value = "fm_user_form_theme", autoResultMap = true)
+public class UserFormThemeEntity  {
+    /**
+     * 琛ㄥ崟key
+     */
+    @NotBlank(message = "formKey涓嶈兘涓虹┖")
+    private String formKey;
+
+    /**
+     * logo鍥剧墖
+     */
+    private String logoImg;
+
+    /**
+     * logo浣嶇疆
+     */
+    private String logoPosition;
+
+    /**
+     * 澶撮儴鍥剧墖
+     */
+    private String headImgUrl;
+
+
+
+    /**
+     * 涓婚棰滆壊
+     */
+    private String themeColor;
+
+    /**
+     * 鎻愪氦鎸夐挳鏂囧瓧
+     */
+    private String submitBtnText;
+
+
+    /**
+     * 鑳屾櫙
+     */
+    private String backgroundColor;
+
+    /**
+     * 鑳屾櫙
+     */
+    private String backgroundImg;
+    /**
+     * 鏄惁鏄剧ず鏍囬
+     */
+    @TableField(typeHandler = BooleanTypeHandler.class)
+    private Boolean showTitle;
+    /**
+     * 鏄惁鏄剧ず鎻忚堪璇�
+     */
+    @TableField(typeHandler = BooleanTypeHandler.class)
+    private Boolean showDescribe;
+    /**
+     * 鏄剧ず搴忓彿
+     */
+    @TableField(typeHandler = BooleanTypeHandler.class)
+    private Boolean showNumber;
+
+    /**
+     * 鏄剧ず鎻愪氦鎸夐挳
+     */
+    @TableField(typeHandler = BooleanTypeHandler.class)
+    private Boolean showSubmitBtn;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormViewCountEntity.java b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormViewCountEntity.java
new file mode 100644
index 0000000..01bb104
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/domain/UserFormViewCountEntity.java
@@ -0,0 +1,36 @@
+package com.ltkj.tduck.domain;
+
+import com.baomidou.mybatisplus.annotation.TableId;
+import com.baomidou.mybatisplus.annotation.TableName;
+import com.ltkj.common.core.domain.BaseEntity;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟鏌ョ湅娆℃暟瀵硅薄 fm_user_form_view_count
+ *
+ * @author tduck
+ * @date 2023-04-04 21:29:39
+ */
+@Data
+@EqualsAndHashCode(callSuper = true)
+@TableName("fm_user_form_view_count")
+public class UserFormViewCountEntity extends BaseEntity {
+
+    private static final long serialVersionUID = 1L;
+
+    /**
+     *
+     */
+    @TableId(value = "id")
+    private Long id;
+    /**
+     * 琛ㄥ崟鍞竴鏍囪瘑
+     */
+    private String formKey;
+    /**
+     *
+     */
+    private Long count;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/EsTypeEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/EsTypeEnum.java
new file mode 100644
index 0000000..07692ea
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/EsTypeEnum.java
@@ -0,0 +1,32 @@
+package com.ltkj.tduck.enums;
+
+
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * ElasticSearch鐨勫瓧娈电被鍨�
+ */
+@AllArgsConstructor
+@Getter
+public enum EsTypeEnum {
+
+    STRING("string", "瀛楃涓茬被鍨�"),
+    TEXT("text", "瀛楃涓茬被鍨�"),
+    KEYWORD("keyword", "瀛楃涓茬被鍨�"),
+    INTEGER("integer", "鏁存暟绫诲瀷"),
+    LONG("long", "鏁存暟绫诲瀷"),
+    SHORT("short", "鏁存暟绫诲瀷"),
+    BYTE("byte", "鏁存暟绫诲瀷"),
+    DOUBLE("double", "娴偣绫诲瀷"),
+    FLOAT("float", "娴偣绫诲瀷"),
+    HALF_FLOAT("half_float", "娴偣绫诲瀷"),
+    SCALED_FLOAT("scaled_float", "娴偣绫诲瀷"),
+    BOOLEAN("boolean", "閫昏緫绫诲瀷"),
+    DATE("date", "鏃ユ湡绫诲瀷");
+
+    private String type;
+    private String name;
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormItemTypeEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormItemTypeEnum.java
new file mode 100644
index 0000000..dac90b6
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormItemTypeEnum.java
@@ -0,0 +1,60 @@
+package com.ltkj.tduck.enums;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author : smalljop
+ * @description : 琛ㄥ崟椤圭被鍨嬫灇涓�
+ * @create : 2020-11-19 10:51
+ **/
+@AllArgsConstructor
+@Getter
+public enum FormItemTypeEnum implements IEnum<String> {
+
+    INPUT("鍗曡鏂囨湰"),
+    NUMBER("鏁板瓧"),
+    TEXTAREA("澶氳鏂囨湰"),
+    SELECT("涓嬫媺妗�"),
+    CASCADER("绾ц仈閫夋嫨"),
+    SORT("鎺掑簭"),
+    SLIDER("婊戝潡"),
+    RADIO("鍗曢�夋"),
+    CHECKBOX("澶氶�夋"),
+    DATE("鏃ユ湡閫夋嫨"),
+    DATE_RANGE("鏃ユ湡鑼冨洿"),
+    RATE("璇勫垎"),
+    IMAGE_UPLOAD("鍥剧墖涓婁紶"),
+    UPLOAD("鏂囦欢涓婁紶缁勪欢"),
+    IMAGE("鍥剧墖灞曠ず"),
+    IMAGE_SELECT("鍥剧墖閫夋嫨"),
+    IMAGE_CAROUSEL("鍥剧墖杞挱"),
+    DESC_TEXT("鏂囧瓧鎻忚堪"),
+    SIGN_PAD("鎵嬪啓绛惧悕"),
+    PAGINATION("鍒嗛〉"),
+    DIVIDER("鍒嗗壊绾�"),
+    PROVINCE_CITY("鐪佸競鑱斿姩"),
+    PHONE_VERIFICATION("鎵嬫満鍙烽獙璇�"),
+    SUB_FORM("瀛愯〃鍗�"),
+    INPUT_MAP("鍦扮悊浣嶇疆"),
+    MATRIX_INPUT("鐭╅樀濉┖"),
+    MATRIX_SCALE("鐭╅樀閲忚〃"),
+    HORIZONTAL_INPUT("妯悜濉┖"),
+    MATRIX_SELECT("鐭╅樀閫夋嫨"),
+    USER_SELECT("鎴愬憳閫夋嫨"),
+    DEPT_SELECT("閮ㄩ棬閫夋嫨"),
+    OCR("鏂囧瓧璇嗗埆"),
+    RANDOM_NUMBER("闅忔満缂栧彿"),
+    FUNCTION_CALC("鍑芥暟璁$畻"),
+    GOODS_SELECT("鍟嗗搧閫夋嫨"),
+    RESERVE_DAY("棰勭害鏃ユ湡"),
+    RESERVE_TIME_RANGE("棰勭害鏃舵");
+    private String desc;
+
+
+    @Override
+    public String getValue() {
+        return this.toString();
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormLogicConditionExpressionEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormLogicConditionExpressionEnum.java
new file mode 100644
index 0000000..2cd28c0
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormLogicConditionExpressionEnum.java
@@ -0,0 +1,28 @@
+package com.ltkj.tduck.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+
+/**
+ * @author : smalljop
+ * @description :閫昏緫鏉′欢
+ * @create : 2020-12-04 13:35
+ **/
+@Getter
+@AllArgsConstructor
+public enum FormLogicConditionExpressionEnum {
+
+    EQ("eq", "绛変簬"),
+    NE("ne", "涓嶇瓑浜�");
+
+
+    @EnumValue
+    @JsonValue
+    private String value;
+
+    private String desc;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormPermsBtnTypeEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormPermsBtnTypeEnum.java
new file mode 100644
index 0000000..406badf
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormPermsBtnTypeEnum.java
@@ -0,0 +1,25 @@
+package com.ltkj.tduck.enums;
+
+
+import lombok.AllArgsConstructor;
+
+/**
+ * 琛ㄥ崟鎸夐挳鏉冮檺绫诲瀷
+ */
+@AllArgsConstructor
+public enum FormPermsBtnTypeEnum {
+    DETAIL("detail", "鏌ョ湅"),
+    ADD("add", "鏂板"),
+    IMPORT("import", "瀵煎叆"),
+    EXPORT("export", "瀵煎嚭"),
+    QUERY("query", "缁撴瀯鏌ヨ"),
+    BATCH_ACTION("batchAction", "鎵归噺鎿嶄綔"),
+    CUSTOM_COLUMN("customColumn", "鑷畾涔夊垪"),
+    UPDATE("update", "缂栬緫"),
+    DELETE("delete", "鍒犻櫎");
+
+
+    private final String code;
+    private final String desc;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormSourceTypeEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormSourceTypeEnum.java
new file mode 100644
index 0000000..23b871f
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormSourceTypeEnum.java
@@ -0,0 +1,30 @@
+package com.ltkj.tduck.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.ltkj.tduck.utils.IDictEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author : smalljop
+ * @description : 琛ㄥ崟鏉ユ簮
+ * @create : 2020-12-04 13:35
+ **/
+
+@Getter
+@AllArgsConstructor
+public enum FormSourceTypeEnum implements IDictEnum {
+
+    BLANK(1, "绌虹櫧鍒涘缓"),
+    TEMPLATE(2, "妯℃澘");
+
+
+    @EnumValue
+    @JsonValue
+    private Integer value;
+
+    private String desc;
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormStatusEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormStatusEnum.java
new file mode 100644
index 0000000..3ae40d1
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormStatusEnum.java
@@ -0,0 +1,31 @@
+package com.ltkj.tduck.enums;
+
+import com.baomidou.mybatisplus.annotation.EnumValue;
+import com.fasterxml.jackson.annotation.JsonValue;
+import com.ltkj.tduck.utils.IDictEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author : smalljop
+ * @description : 琛ㄥ崟鐘舵��
+ * @create : 2020-12-04 13:35
+ **/
+@Getter
+@AllArgsConstructor
+@NoArgsConstructor
+public enum FormStatusEnum implements IDictEnum<Integer> {
+
+    CREATE(1, "鏈彂甯�"),
+    RELEASE(2, "鏀堕泦涓�"),
+    STOP(3, "鍋滄鍙戝竷");
+
+
+    @EnumValue
+    @JsonValue
+    private Integer value;
+
+    private String desc;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormTypeEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormTypeEnum.java
new file mode 100644
index 0000000..511a962
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/FormTypeEnum.java
@@ -0,0 +1,38 @@
+package com.ltkj.tduck.enums;
+
+import com.ltkj.tduck.utils.IDictEnum;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
+
+/**
+ * @author : smalljop
+ * @description : 琛ㄥ崟绫诲瀷
+ * @create : 2020-12-04 13:35
+ **/
+@Getter
+@AllArgsConstructor
+public enum FormTypeEnum implements IDictEnum {
+
+
+    /**
+     * 鏅�氳〃鍗�
+     */
+    ORDINARY(1, "鏅�氳〃鍗�"),
+    /**
+     * 娴佺▼琛ㄥ崟
+     */
+    WORKFLOW(2, "娴佺▼琛ㄥ崟"),
+    /**
+     * 鏂囦欢澶�
+     */
+    FOLDER(3, "鏂囦欢澶�"),
+    /**
+     * 鑰冭瘯
+     */
+    EXAM(4, "鑰冭瘯");
+
+    private Integer value;
+    private String desc;
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/enums/TimeRangeEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/enums/TimeRangeEnum.java
new file mode 100644
index 0000000..0dc3a2b
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/enums/TimeRangeEnum.java
@@ -0,0 +1,57 @@
+
+package com.ltkj.tduck.enums;
+
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author : tduck
+ * @description : 鏃堕棿鑼冨洿鏋氫妇
+ * @create :  2022/10/11 11:12
+ **/
+@NoArgsConstructor
+@Getter
+public enum TimeRangeEnum {
+    /**
+     * 浠婂ぉ
+     */
+    TODAY,
+    /**
+     * 鏄ㄥぉ
+     */
+    YESTERDAY,
+    /**
+     * 杩�7澶�
+     */
+    WEEK,
+    /**
+     * 涓婂懆
+     */
+    LAST_WEEK,
+    /**
+     * 鏈湀
+     */
+    MONTH,
+    /**
+     * 涓婃湀
+     */
+    LAST_MONTH,
+    /**
+     * 鏈搴�
+     */
+    QUARTER,
+    /**
+     * 涓婂搴�
+     */
+    LAST_QUARTER,
+    /**
+     * 鏈勾
+     */
+    YEAR,
+    /**
+     * 鍘诲勾
+     */
+    LAST_YEAR;
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/handler/AutoFillMetaInfoHandler.java b/ltkj-system/src/main/java/com/ltkj/tduck/handler/AutoFillMetaInfoHandler.java
new file mode 100644
index 0000000..e5e103a
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/handler/AutoFillMetaInfoHandler.java
@@ -0,0 +1,30 @@
+//package com.ltkj.tduck.handler;
+//
+//import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
+//import com.ltkj.tduck.domain.TBaseEntity;
+//import lombok.extern.slf4j.Slf4j;
+//import org.apache.ibatis.reflection.MetaObject;
+//import org.springframework.stereotype.Component;
+//
+//import java.time.LocalDateTime;
+//
+///**
+// * @author smalljop
+// * mybatis 鑷姩濉厖鎻掍欢
+// * @link https://baomidou.com/guide/typehandler.html
+// */
+//@Slf4j
+//@Component
+//public class AutoFillMetaInfoHandler implements MetaObjectHandler {
+//
+//    @Override
+//    public void insertFill(MetaObject metaObject) {
+//        this.setFieldValByName(TBaseEntity.Fields.createTime, LocalDateTime.now(), metaObject);
+//        this.setFieldValByName(TBaseEntity.Fields.updateTime, LocalDateTime.now(), metaObject);
+//    }
+//
+//    @Override
+//    public void updateFill(MetaObject metaObject) {
+//        this.setFieldValByName(TBaseEntity.Fields.updateTime, LocalDateTime.now(), metaObject);
+//    }
+//}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/handler/BooleanTypeHandler.java b/ltkj-system/src/main/java/com/ltkj/tduck/handler/BooleanTypeHandler.java
new file mode 100644
index 0000000..273613f
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/handler/BooleanTypeHandler.java
@@ -0,0 +1,47 @@
+
+package com.ltkj.tduck.handler;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+/**
+ * 澶勭悊甯冨皵杞崲 mysql鑳借嚜鍔ㄨ浆鎹�
+ * 鏈夌殑鏁版嵁搴撲笉鏀寔鑷姩杞崲 pgsql涓嶈 骞茶剢缁熶竴澶勭悊浜�
+ *
+ * @author tduck
+ */
+public class BooleanTypeHandler extends BaseTypeHandler<Boolean> {
+
+    public BooleanTypeHandler() {
+    }
+
+    @Override
+    public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType) throws SQLException {
+        ps.setInt(i, parameter ? 1 : 0);
+    }
+
+    @Override
+    public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {
+        boolean result = rs.getInt(columnName) != 0;
+        return !result && rs.wasNull() ? null : result;
+    }
+
+    @Override
+    public Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
+        boolean result = rs.getInt(columnIndex) != 0;
+        return !result && rs.wasNull() ? null : result;
+    }
+
+    @Override
+    public Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
+        boolean result = cs.getInt(columnIndex) != 0;
+        return !result && cs.wasNull() ? null : result;
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/handler/JacksonTypeHandler.java b/ltkj-system/src/main/java/com/ltkj/tduck/handler/JacksonTypeHandler.java
new file mode 100644
index 0000000..00f5b1d
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/handler/JacksonTypeHandler.java
@@ -0,0 +1,64 @@
+package com.ltkj.tduck.handler;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Assert;
+import com.baomidou.mybatisplus.extension.handlers.AbstractJsonTypeHandler;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ltkj.tduck.utils.JsonUtils;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.ibatis.type.JdbcType;
+import org.apache.ibatis.type.MappedJdbcTypes;
+import org.apache.ibatis.type.MappedTypes;
+
+import java.io.IOException;
+
+/**
+ * Jackson 瀹炵幇 JSON 瀛楁绫诲瀷澶勭悊鍣�
+ *
+ * @author hubin
+ * @since 2019-08-25
+ */
+@Slf4j
+@MappedTypes({Object.class})
+@MappedJdbcTypes(JdbcType.VARCHAR)
+public class JacksonTypeHandler extends AbstractJsonTypeHandler<Object> {
+    private static ObjectMapper objectMapper = new ObjectMapper();
+    private Class<?> type;
+
+    public JacksonTypeHandler(Class<?> type) {
+        if (log.isTraceEnabled()) {
+            log.trace("JacksonTypeHandler(" + type + ")");
+        }
+        Assert.notNull(type, "Type argument cannot be null");
+        this.type = type;
+    }
+
+    public static void setObjectMapper(ObjectMapper objectMapper) {
+        Assert.notNull(objectMapper, "ObjectMapper should not be null");
+        JacksonTypeHandler.objectMapper = JsonUtils.getInstance();
+    }
+
+    @Override
+    protected Object parse(String json) {
+        try {
+            if (StrUtil.isBlank(json)) {
+                return null;
+            }
+            return objectMapper.readValue(json, type);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    @Override
+    protected String toJson(Object obj) {
+        try {
+            return JsonUtils.objToJsonIgnoreNull(obj);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        } catch (Exception e) {
+            throw new RuntimeException(e);
+        }
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/handler/LongToStringSerializer.java b/ltkj-system/src/main/java/com/ltkj/tduck/handler/LongToStringSerializer.java
new file mode 100644
index 0000000..070cc44
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/handler/LongToStringSerializer.java
@@ -0,0 +1,34 @@
+package com.ltkj.tduck.handler;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+
+/**
+ * @author : wangqing
+ * @description : Long杞瑂tring 閬垮厤杩斿洖鍓嶇涓㈠け绮惧害
+ * @create :  2022/03/10 15:07
+ **/
+
+public class LongToStringSerializer extends JsonSerializer<Long> {
+
+
+    /**
+     * Method that can be called to ask implementation to serialize
+     * values of type this serializer handles.
+     *
+     * @param value       Value to serialize; can <b>not</b> be null.
+     * @param gen         Generator used to output resulting Json content
+     * @param serializers Provider that can be used to get serializers for
+     */
+    @Override
+    public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+        if (value != null && value.toString().length() > 16) {
+            gen.writeString(value.toString());
+        } else {
+            gen.writeNumber(value);
+        }
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormTemplateCategoryMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormTemplateCategoryMapper.java
new file mode 100644
index 0000000..d1c7505
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormTemplateCategoryMapper.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.FormTemplateCategoryEntity;
+
+/**
+ * 琛ㄥ崟妯℃澘鍒嗙被(FormTemplateType)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author smalljop
+ * @since 2021-01-06 10:51:05
+ */
+public interface FormTemplateCategoryMapper extends BaseMapper<FormTemplateCategoryEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormThemeMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormThemeMapper.java
new file mode 100644
index 0000000..ec4a1c1
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/FormThemeMapper.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.FormThemeEntity;
+
+/**
+ * 琛ㄥ崟涓婚澶栬妯℃澘(FormTheme)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author smalljop
+ * @since 2020-11-23 18:33:54
+ */
+public interface FormThemeMapper extends BaseMapper<FormThemeEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormDataMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormDataMapper.java
new file mode 100644
index 0000000..d88dac1
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormDataMapper.java
@@ -0,0 +1,54 @@
+package com.ltkj.tduck.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Results;
+import org.apache.ibatis.annotations.Select;
+
+import java.util.List;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟鏁版嵁(FormResult)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author smalljop
+ * @since 2020-11-23 14:09:21
+ */
+public interface UserFormDataMapper extends BaseMapper<UserFormDataEntity> {
+
+    /**
+     * 鏌ヨ琛ㄥ崟瀛楁鍊兼槸鍚﹀瓨鍦�
+     * @param formKey 琛ㄥ崟key
+     * @param field 瀛楁
+     * @param value 鍊�
+     * @return 鏄惁瀛樺湪
+     */
+    @Select("SELECT COUNT(id) FROM fm_user_form_data WHERE form_key = #{formKey} AND JSON_EXTRACT(original_data, '$.\"${field}\"') = #{value}")
+    Long selectOriginalDataValueCount(@Param("formKey") String formKey, @Param("field") String field, @Param("value") Object value);
+
+
+    /**
+     * 鏌ヨ琛ㄥ崟鏁版嵁
+     * @param sql sql
+     * @return
+     */
+    @Results(id="queryRowsResultMap",
+            value = {
+                    @Result(property = "originalData", column = "original_data",typeHandler = JacksonTypeHandler.class),
+                    @Result(property = "wxUserInfo", column = "wx_user_info",typeHandler = JacksonTypeHandler.class)})
+    @Select("${sql}")
+    List<UserFormDataEntity> selectRowsBySql(@Param("sql") String sql);
+
+
+    /**
+     * 鏌ヨ琛ㄥ崟鏁版嵁鏉℃暟
+     * @param sql
+     * @return
+     */
+    @Select("${sql}")
+    Long selectCountBySql(@Param("sql") String sql);
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormItemMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormItemMapper.java
new file mode 100644
index 0000000..4ebc4c9
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormItemMapper.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.UserFormItemEntity;
+
+/**
+ * 琛ㄥ崟椤�(FormItem)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author smalljop
+ * @since 2020-11-19 10:49:17
+ */
+public interface UserFormItemMapper extends BaseMapper<UserFormItemEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormLogicMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormLogicMapper.java
new file mode 100644
index 0000000..a432273
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormLogicMapper.java
@@ -0,0 +1,15 @@
+package com.ltkj.tduck.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.UserFormLogicEntity;
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟閫昏緫琛�(UserFormLogic)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author smalljop
+ * @since 2020-11-18 18:16:17
+ */
+public interface UserFormLogicMapper extends BaseMapper<UserFormLogicEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormMapper.java
new file mode 100644
index 0000000..6ccf348
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormMapper.java
@@ -0,0 +1,12 @@
+package com.ltkj.tduck.mapper;
+
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.UserFormEntity;
+
+/**
+ * 琛ㄥ崟琛�(Form)琛ㄦ暟鎹簱璁块棶灞�
+ */
+public interface UserFormMapper extends BaseMapper<UserFormEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormSettingMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormSettingMapper.java
new file mode 100644
index 0000000..ba7be3a
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormSettingMapper.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.UserFormSettingEntity;
+
+/**
+ * 琛ㄥ崟璁剧疆
+ *
+ * @author tduck
+ * @date 2021-08-12 16:19:57
+ */
+public interface UserFormSettingMapper extends BaseMapper<UserFormSettingEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormThemeMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormThemeMapper.java
new file mode 100644
index 0000000..bba129f
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormThemeMapper.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.UserFormThemeEntity;
+
+/**
+ * 琛ㄥ崟涓婚(UserFormTheme)琛ㄦ暟鎹簱璁块棶灞�
+ *
+ * @author smalljop
+ * @since 2020-11-25 13:36:31
+ */
+public interface UserFormThemeMapper extends BaseMapper<UserFormThemeEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormViewCountMapper.java b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormViewCountMapper.java
new file mode 100644
index 0000000..73b5470
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/mapper/UserFormViewCountMapper.java
@@ -0,0 +1,24 @@
+package com.ltkj.tduck.mapper;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.ltkj.tduck.domain.UserFormViewCountEntity;
+import org.apache.ibatis.annotations.Param;
+import org.apache.ibatis.annotations.Update;
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟鏌ョ湅娆℃暟Mapper鎺ュ彛
+ *
+ * @author tduck
+ * @date 2023-04-04 21:29:39
+ */
+public interface UserFormViewCountMapper extends BaseMapper<UserFormViewCountEntity> {
+
+
+    /**
+     * 鏌ョ湅娆℃暟鑷
+     *
+     * @param formKey 琛ㄥ崟key
+     */
+    @Update("update fm_user_form_view_count set count = count + 1 , update_time=now() where form_key = #{formKey}")
+    void incrementCount(@Param("formKey") String formKey);
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/request/CheckWritePwdRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/request/CheckWritePwdRequest.java
new file mode 100644
index 0000000..b335335
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/request/CheckWritePwdRequest.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.request;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+@Data
+public class CheckWritePwdRequest {
+
+    @NotBlank
+    private String formKey;
+    @NotBlank
+    private String password;
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormItemRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormItemRequest.java
new file mode 100644
index 0000000..21b4634
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormItemRequest.java
@@ -0,0 +1,25 @@
+package com.ltkj.tduck.request;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+
+/**
+ * @author : smalljop
+ * @description : 鏌ヨ琛ㄥ崟闂
+ * @create :  2021/06/03 14:45
+ **/
+@Data
+public class QueryFormItemRequest {
+
+    /**
+     * 琛ㄥ崟key
+     */
+    @NotBlank
+    private String key;
+    /**
+     * 鏄樉绀虹被鍨�
+     */
+    private Boolean displayType;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormRequest.java
new file mode 100644
index 0000000..2075880
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormRequest.java
@@ -0,0 +1,53 @@
+package com.ltkj.tduck.request;
+
+import cn.hutool.core.date.DatePattern;
+import com.ltkj.tduck.domain.PageRequest;
+import lombok.Data;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import java.time.LocalDateTime;
+
+/**
+ * @author : smalljop
+ * @description : 鏌ヨ琛ㄥ崟
+ * @create : 2020-12-10 15:04
+ **/
+@Data
+public class QueryFormRequest {
+
+
+    @Data
+    public static class List {
+        private Integer status;
+    }
+
+
+    /**
+     * 鍒嗛〉鏌ヨ
+     */
+    @Data
+    public static class Page extends PageRequest {
+        private Long folderId;
+
+
+        private Integer type;
+        private Integer status;
+
+        private String name;
+
+        /**
+         * 鏄惁鍖呭惈鏂囦欢澶�
+         */
+        private Boolean folder;
+
+        @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+        private LocalDateTime beginDateTime;
+
+        @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+        private LocalDateTime endDateTime;
+    }
+
+
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormResultRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormResultRequest.java
new file mode 100644
index 0000000..0c91817
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormResultRequest.java
@@ -0,0 +1,60 @@
+package com.ltkj.tduck.request;
+
+import cn.hutool.core.date.DatePattern;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+import lombok.experimental.FieldNameConstants;
+import org.springframework.format.annotation.DateTimeFormat;
+
+import javax.validation.constraints.NotBlank;
+import java.time.LocalDateTime;
+import java.util.List;
+
+/**
+ * @author : smalljop
+ * @description : 琛ㄥ崟缁撴灉鏌ヨ
+ * @create : 2020-12-08 15:55
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+@FieldNameConstants
+public class QueryFormResultRequest {
+
+    /**
+     * 褰撳墠椤�
+     */
+    private Integer current;
+    /**
+     * 澶у皬
+     */
+    private Integer size;
+
+    /**
+     * 鍥哄畾瀛楁
+     */
+    @NotBlank
+    private String formKey;
+
+    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+    private LocalDateTime beginDateTime;
+    @DateTimeFormat(pattern = DatePattern.NORM_DATETIME_PATTERN)
+    private LocalDateTime endDateTime;
+
+    /**
+     * 琚煡璇㈢殑瀛楁
+     */
+    private String[] filterFields;
+
+    /**
+     * 鏁版嵁id 闆嗗悎
+     */
+    private List<String> dataIds;
+
+
+    private Long inCode;
+
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormTemplateTypeRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormTemplateTypeRequest.java
new file mode 100644
index 0000000..0e8a2c0
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/request/QueryFormTemplateTypeRequest.java
@@ -0,0 +1,18 @@
+package com.ltkj.tduck.request;
+
+import lombok.Data;
+
+/**
+ * @author : smalljop
+ * @description : 鏌ヨ琛ㄥ崟妯℃澘鍒嗛〉
+ * @create : 2020-12-10 15:04
+ **/
+@Data
+public class QueryFormTemplateTypeRequest {
+
+
+    @Data
+    public static class List {
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/request/SortFormItemRequest.java b/ltkj-system/src/main/java/com/ltkj/tduck/request/SortFormItemRequest.java
new file mode 100644
index 0000000..abe1a7d
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/request/SortFormItemRequest.java
@@ -0,0 +1,28 @@
+package com.ltkj.tduck.request;
+
+import lombok.Data;
+
+import javax.validation.constraints.NotBlank;
+import javax.validation.constraints.NotNull;
+
+/**
+ * @author : smalljop
+ * @description : 鎺掑簭琛ㄥ崟椤�
+ * @create : 2020-11-20 10:14
+ **/
+@Data
+public class SortFormItemRequest {
+    /**
+     * 琛ㄥ崟Id
+     */
+    @NotNull(message = "key璇锋眰寮傚父")
+    private String formKey;
+
+
+    private Long beforePosition;
+
+    private Long afterPosition;
+    @NotBlank(message = "formItemId璇锋眰寮傚父")
+    private String formItemId;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/FormTemplateCategoryService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/FormTemplateCategoryService.java
new file mode 100644
index 0000000..6f9622d
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/FormTemplateCategoryService.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.FormTemplateCategoryEntity;
+
+/**
+ * 琛ㄥ崟妯℃澘鍒嗙被(FormTemplateType)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author smalljop
+ * @since 2021-01-06 10:51:06
+ */
+public interface FormTemplateCategoryService extends IService<FormTemplateCategoryEntity> {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/FormThemeService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/FormThemeService.java
new file mode 100644
index 0000000..8b5c986
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/FormThemeService.java
@@ -0,0 +1,56 @@
+package com.ltkj.tduck.service;
+
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.FormThemeEntity;
+
+/**
+ * 琛ㄥ崟涓婚澶栬妯℃澘(FormTheme)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author smalljop
+ * @since 2020-11-23 18:33:55
+ */
+public interface FormThemeService extends IService<FormThemeEntity> {
+
+//    /**
+//     * 鑾峰彇涓婚鍒嗙被
+//     *
+//     * @return
+//     */
+//    List<FormThemeCategoryEntity> listThemeCategories();
+//
+//    /**
+//     * 鑾峰彇琛ㄥ崟鍒嗙被
+//     *
+//     * @param categoryId
+//     * @return
+//     */
+//    FormThemeCategoryEntity getThemeCategory(Long categoryId);
+//
+//    /**
+//     * 淇濆瓨涓婚鍒嗙被
+//     *
+//     * @param entity
+//     * @return
+//     */
+//    Boolean saveThemeCategory(FormThemeCategoryEntity entity);
+//
+//    /**
+//     * 淇敼涓婚鍒嗙被
+//     *
+//     * @param entity
+//     * @return
+//     */
+//    Boolean updateThemeCategory(FormThemeCategoryEntity entity);
+//
+//    /**
+//     * 鍒犻櫎涓婚鍒嗙被
+//     *
+//     * @param categoryId
+//     * @return
+//     */
+//    Boolean deleteThemeCategory(List<Long> categoryIds);
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormDataService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormDataService.java
new file mode 100644
index 0000000..475fdeb
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormDataService.java
@@ -0,0 +1,69 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import com.ltkj.tduck.request.QueryFormResultRequest;
+import com.ltkj.tduck.utils.Result;
+import com.ltkj.tduck.vo.FormDataTableVO;
+
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(FormResult)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author smalljop
+ * @since 2020-11-23 14:09:22
+ */
+public interface UserFormDataService extends IService<UserFormDataEntity> {
+
+
+    /**
+     * 淇濆瓨缁撴灉
+     *
+     * @param entity 琛ㄥ崟鏁版嵁
+     * @return 缁撴灉
+     */
+    Map<String, Object> saveFormResult(UserFormDataEntity entity);
+
+//    /**
+//     * 涓嬭浇琛ㄥ崟缁撴灉涓殑闄勪欢
+//     *
+//     * @param request 璇锋眰
+//     * @return
+//     */
+//    Result downloadFormResultFile(QueryFormResultRequest request);
+
+
+    /**
+     * 鏌ヨ琛ㄥ崟鏁版嵁
+     *
+     * @param request
+     * @return
+     */
+    FormDataTableVO listFormDataTable(QueryFormResultRequest request);
+
+//    /**
+//     * 鏍规嵁Id鍒犻櫎
+//     *
+//     * @param dataIdList
+//     * @param formKey
+//     * @return
+//     */
+//    Boolean deleteByIds(List<String> dataIdList, String formKey);
+//
+//    /**
+//     * 淇敼
+//     *
+//     * @param entity
+//     * @return
+//     */
+//    Boolean updateFormResult(UserFormDataEntity entity);
+//
+    /**
+     * 鑾峰彇鏁版嵁璇︽儏
+     *
+     * @param dataId
+     * @return
+     */
+    Result getFormDataDetails(String dataId);
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormItemService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormItemService.java
new file mode 100644
index 0000000..69718ff
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormItemService.java
@@ -0,0 +1,60 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormItemEntity;
+import com.ltkj.tduck.vo.FormFieldVO;
+
+import java.util.List;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(FormItem)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author smalljop
+ * @since 2020-11-19 10:49:17
+ */
+public interface UserFormItemService extends IService<UserFormItemEntity> {
+
+
+//    /**
+//     * 鏍规嵁key鏌ヨ
+//     *
+//     * @param key
+//     * @return
+//     */
+//    List<UserFormItemEntity> listByFormKey(String key);
+//
+    /**
+     * 鏌ヨ鑷畾涔夊瓧娈�
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 鑷畾涔夊瓧娈�
+     */
+    List<FormFieldVO> listFormFields(String formKey);
+
+    /**
+     * 鏌ヨ鍏ㄩ儴瀛楁 鍖呭惈榛樿瀛楁
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 鑷畾涔夊瓧娈�
+     */
+    List<FormFieldVO> listAllFormFields(String formKey);
+
+
+    /**
+     * 鏌ヨ鏈�鍚庝竴涓瓧娈电殑鎺掑簭鍊�
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 鎺掑簭鍊�
+     */
+    Long getLastItemSort(String formKey);
+//
+    /**
+     * 妫�鏌ュ瓧娈垫槸鍚︽槸闇�瑕佺壒娈婂鐞嗗瓧娈� 姣斿闅忔満缂栧彿
+     *
+     * @param userFormItemEntity 瀛楁
+     * @return true 闇�瑕佺壒娈婂鐞�
+     */
+    Boolean isSpecialTypeItem(UserFormItemEntity userFormItemEntity);
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormLogicService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormLogicService.java
new file mode 100644
index 0000000..679dacc
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormLogicService.java
@@ -0,0 +1,7 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormLogicEntity;
+
+public interface UserFormLogicService extends IService<UserFormLogicEntity> {
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormService.java
new file mode 100644
index 0000000..31d4e06
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormService.java
@@ -0,0 +1,24 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormEntity;
+
+/**
+ * 琛ㄥ崟琛�(Form)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author smalljop
+ * @since 2020-11-18 18:16:18
+ */
+public interface UserFormService extends IService<UserFormEntity> {
+
+
+    /**
+     * 鏍规嵁key鑾峰彇
+     *
+     * @param key key
+     * @return UserFormEntity
+     */
+    UserFormEntity getByKey(final String key);
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormSettingService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormSettingService.java
new file mode 100644
index 0000000..978225f
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormSettingService.java
@@ -0,0 +1,61 @@
+package com.ltkj.tduck.service;
+
+
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormSettingEntity;
+import com.ltkj.tduck.struct.FormSettingSchemaStruct;
+import com.ltkj.tduck.utils.Result;
+
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟璁剧疆
+ *
+ * @author smalljop
+ * @since 2020-11-30 14:00:52
+ */
+public interface UserFormSettingService extends IService<UserFormSettingEntity> {
+    /**
+     * 淇濆瓨琛ㄥ崟璁剧疆
+     */
+    Boolean saveFormSetting(Map<String, Object> params);
+
+
+    /**
+     * 琛ㄥ崟璁剧疆
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 璁剧疆椤�
+     */
+    UserFormSettingEntity getFormSettingByKey(String formKey);
+
+    /**
+     * 璁剧疆鍏蜂綋瀹氫箟璁剧疆椤�
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 璁剧疆椤�
+     */
+    FormSettingSchemaStruct getFormSettingSchema(String formKey);
+
+    /**
+     * 鑾峰彇褰撳墠椤圭洰璁剧疆鐨勭姸鎬�
+     * 鏄惁鍙互濉啓绛�
+     *
+     * @param formKey   琛ㄥ崟key
+     * @param requestIp 璇锋眰ip
+     * @param wxOpenId  寰俊openid
+     * @param type      绫诲瀷 1鍏紑濉啓 2.鎸囧畾濉啓
+     * @return 鏄惁鍙互濉啓
+     */
+    Result<Boolean> getUserFormWriteSettingStatus(String formKey, String requestIp, String wxOpenId, Integer type);
+
+
+    /**
+     * 鍒犻櫎琛ㄥ崟鎵�鏈夎缃�
+     *
+     * @param key 琛ㄥ崟key
+     * @return 鏄惁鍒犻櫎鎴愬姛
+     */
+    Boolean deleteAllSetting(String key);
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormThemeService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormThemeService.java
new file mode 100644
index 0000000..d8114fe
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormThemeService.java
@@ -0,0 +1,21 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormThemeEntity;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(UserFormTheme)琛ㄦ湇鍔℃帴鍙�
+ *
+ * @author smalljop
+ * @since 2020-11-25 13:36:31
+ */
+public interface UserFormThemeService extends IService<UserFormThemeEntity> {
+
+    /**
+     * 鑾峰彇琛ㄥ崟涓婚璇︽儏
+     *
+     * @param key
+     * @return
+     */
+    UserFormThemeEntity getByKey(String key);
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormViewCountService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormViewCountService.java
new file mode 100644
index 0000000..74803ca
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/UserFormViewCountService.java
@@ -0,0 +1,27 @@
+package com.ltkj.tduck.service;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.ltkj.tduck.domain.UserFormViewCountEntity;
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟鏌ョ湅娆℃暟Service鎺ュ彛
+ *
+ * @author tduck
+ * @date 2023-04-04 21:29:39
+ */
+public interface UserFormViewCountService extends IService<UserFormViewCountEntity> {
+
+    /**
+     * 鏌ョ湅娆℃暟鑷
+     *
+     * @param formKey 琛ㄥ崟key
+     */
+    void increment(String formKey);
+
+    /**
+     * 鏌ョ湅娆℃暟
+     *
+     * @param formKey 琛ㄥ崟key
+     */
+    Long count(String formKey);
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataBaseService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataBaseService.java
new file mode 100644
index 0000000..77ecf22
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataBaseService.java
@@ -0,0 +1,135 @@
+package com.ltkj.tduck.service.data;
+
+import com.ltkj.tduck.request.QueryFormResultRequest;
+import com.ltkj.tduck.vo.FormDataTableVO;
+
+/**
+ * @author : tduck
+ * @description : 琛ㄥ崟鏁版嵁鍩虹鏈嶅姟
+ * @create :  2022/07/04 13:50
+ **/
+public abstract class FormDataBaseService {
+
+
+    /***
+     * 琛ㄥ崟瀛楁鍊兼槸鍚﹀瓨鍦�
+     * @param formKey 琛ㄥ崟key
+     * @param formItemId 琛ㄥ崟瀛楁id
+     * @param value 瀛楁鍊�
+     * @return true 瀛樺湪 false 涓嶅瓨鍦�
+     */
+    public abstract Boolean valueExist(String formKey, String formItemId, Object value);
+
+
+    /**
+     * 鍚屾琛ㄥ崟鏁版嵁
+     *
+     * @param result 琛ㄥ崟鏁版嵁
+     * @return 鏄惁鍚屾鎴愬姛
+     */
+//    public abstract Boolean syncSaveData(UserFormDataEntity result);
+//
+//    /**
+//     * 鍚屾鏇存柊鏁版嵁
+//     *
+//     * @param result 琛ㄥ崟鏁版嵁
+//     */
+//    public abstract Boolean asyncUpdateData(UserFormDataEntity result);
+//
+//    /**
+//     * 鍒犻櫎琛ㄥ崟鏁版嵁
+//     *
+//     * @param idList  琛ㄥ崟鏁版嵁id鍒楄〃
+//     * @param formKey 琛ㄥ崟key
+//     */
+//    public abstract void asyncDeleteData(List<String> idList, String formKey);
+//
+    /**
+     * 鏌ヨ琛ㄥ崟鏁版嵁
+     *
+     * @param request 鏌ヨ鍐呭
+     */
+    public abstract FormDataTableVO search(QueryFormResultRequest request);
+//
+//
+//    /**
+//     * 鏌ヨ鍏ㄩ儴鏁版嵁
+//     */
+//    public abstract List<Map> searchAll(QueryFormResultRequest request);
+//
+//
+//    /**
+//     * 鏋勯�犳椂闂磋寖鍥存煡璇�
+//     *
+//     * @param condition 鏉′欢
+//     * @return 鏃堕棿鑼冨洿
+//     */
+//    protected Map<String, DateTime> getRangDateTime(FormDataFilterStruct.Condition condition) {
+//        if (ObjectUtil.isNull(condition.getValue())) {
+//            return null;
+//        }
+//        DateTime beginDate = null;
+//        DateTime endDate = null;
+//        TimeRangeEnum timeRangeEnum = TimeRangeEnum.valueOf(condition.getValue().toString());
+//        switch (timeRangeEnum) {
+//            case TODAY:
+//                beginDate = DateUtil.beginOfDay(new Date());
+//                endDate = DateUtil.endOfDay(new Date());
+//                break;
+//            case YESTERDAY:
+//                beginDate = DateUtil.beginOfDay(DateUtil.yesterday());
+//                endDate = DateUtil.endOfDay(DateUtil.yesterday());
+//                break;
+//            case WEEK:
+//                beginDate = DateUtil.beginOfWeek(new Date());
+//                endDate = DateUtil.endOfWeek(new Date());
+//                break;
+//            case LAST_WEEK:
+//                beginDate = DateUtil.beginOfWeek(DateUtil.lastWeek());
+//                endDate = DateUtil.endOfWeek(DateUtil.lastWeek());
+//                break;
+//            case MONTH:
+//                beginDate = DateUtil.beginOfMonth(new Date());
+//                endDate = DateUtil.endOfMonth(new Date());
+//                break;
+//            case LAST_MONTH:
+//                beginDate = DateUtil.beginOfMonth(DateUtil.lastMonth());
+//                endDate = DateUtil.endOfMonth(DateUtil.lastMonth());
+//                break;
+//            case YEAR:
+//                beginDate = DateUtil.beginOfYear(new Date());
+//                endDate = DateUtil.endOfYear(new Date());
+//                break;
+//            case LAST_YEAR:
+//                Date lastYear = DateUtil.offset(new Date(), DateField.YEAR, -1);
+//                beginDate = DateUtil.beginOfYear(lastYear);
+//                endDate = DateUtil.endOfYear(lastYear);
+//                break;
+//            default:
+//                beginDate = DateUtil.date();
+//                endDate = DateUtil.date();
+//                break;
+//        }
+//        Map<String, DateTime> result = MapUtil.newHashMap();
+//        result.put("beginDate", beginDate);
+//        result.put("endDate", endDate);
+//        return result;
+//    }
+//
+//
+//    public static Map<String, Object> convertDocument(UserFormDataEntity result) {
+//        Map<String, Object> processData = result.getOriginalData();
+//        Map<String, Object> resultMap = BeanUtil.beanToMap(result);
+//        //鏍煎紡鍖栨椂闂�
+//
+////        resultMap.put(BaseEntity.Fields.updateTime, LocalDateTimeUtil.formatNormal(result.getUpdateTime()));
+////        resultMap.put(BaseEntity.Fields.createTime, LocalDateTimeUtil.formatNormal(result.getCreateTime()));
+//        resultMap.remove(UserFormDataEntity.Fields.originalData);
+//        processData.putAll(resultMap);
+//        processData.remove(SysBaseEntity.Fields.searchValue);
+//        processData.remove(SysBaseEntity.Fields.params);
+//        return processData;
+//    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataMysqlService.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataMysqlService.java
new file mode 100644
index 0000000..f91187e
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/data/FormDataMysqlService.java
@@ -0,0 +1,139 @@
+package com.ltkj.tduck.service.data;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.ltkj.system.service.ISysConfigService;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import com.ltkj.tduck.mapper.UserFormDataMapper;
+import com.ltkj.tduck.request.QueryFormResultRequest;
+import com.ltkj.tduck.vo.FormDataTableVO;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import javax.annotation.Resource;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+
+/**
+ * @author : wangqing
+ * @description : 琛ㄥ崟鏁版嵁鍩虹鏈嶅姟
+ * @create :  2022/07/04 14:25
+ **/
+@Service
+@Slf4j
+public class FormDataMysqlService extends FormDataBaseService {
+
+    @Autowired
+    private UserFormDataMapper userFormDataMapper;
+
+
+
+    @Autowired
+    private ISysConfigService configService;
+
+//    @Autowired(required = false)
+//    private TduckMongoTemplate mongoTemplate;
+//
+//
+    @Override
+    public Boolean valueExist(String formKey, String formItemId, Object value) {
+        return userFormDataMapper.selectOriginalDataValueCount(formKey, formItemId, value) > 0;
+    }
+//
+//    @Override
+//    public Boolean syncSaveData(UserFormDataEntity result) {
+//        if (null == mongoTemplate) {
+//            return true;
+//        }
+//        mongoTemplate.save(convertDocument(result), result.getFormKey());
+//        return true;
+//    }
+//
+//
+//    @Override
+//    public Boolean asyncUpdateData(UserFormDataEntity result) {
+//        if (null == mongoTemplate) {
+//            return true;
+//        }
+//        mongoTemplate.updateById(convertDocument(result), result.getId(), result.getFormKey());
+//        return true;
+//    }
+//
+//    @Override
+//    public void asyncDeleteData(List<String> idList, String formKey) {
+//        if (null == mongoTemplate) {
+//            return;
+//        }
+//        mongoTemplate.deleteByIds(idList, formKey);
+//    }
+
+
+    @Override
+    public FormDataTableVO search(QueryFormResultRequest request) {
+        // 鎷兼帴sql
+        StringBuilder sqlBuilder = new StringBuilder();
+        sqlBuilder.append("select * from fm_user_form_data where form_key = '").append(request.getFormKey()).append("'");
+
+        //1. 鎷兼帴鏉′欢 鏌ヨ鏉′欢 鐢ㄥぇ鎷彿鍖呰捣鏉� 閲岄潰鐨勬潯浠朵細鎷兼帴 OR 鎴栬�� AND 涓嶈兘褰卞搷鍏朵粬榛樿闄勫甫鏉′欢 姣斿form_key 鍚﹀垯浼氶敊璇煡璇�
+        StringBuilder whereBuilder = new StringBuilder();
+
+        // 鏌ヨ鎸囧畾id鏁版嵁
+        if (ObjectUtil.isNotNull(request.getDataIds()) && 0 != request.getDataIds().size()) {
+            whereBuilder.append(" and id in (").append(CollUtil.join(request.getDataIds(), ",")).append(")");
+        }
+        // 鍏堟煡璇㈡�绘暟锛屾煡璇㈡�绘暟鍚庡啀杩涜鎷兼帴order by 鍙� limit 璇彞
+        StringBuilder countBuilder = new StringBuilder("select count(1) from fm_user_form_data where form_key = '").append(request.getFormKey()).append("'");
+        countBuilder.append(whereBuilder);
+        Long total = userFormDataMapper.selectCountBySql(countBuilder.toString());
+
+        whereBuilder.append(" ORDER BY id DESC");
+        // 鍒嗛〉
+        if (ObjectUtil.isNotNull(request.getCurrent()) && ObjectUtil.isNotNull(request.getSize())) {
+            whereBuilder.append(" limit ").append(request.getCurrent() * request.getSize()).append(",").append(request.getSize());
+        }
+        sqlBuilder.append(whereBuilder);
+        List<UserFormDataEntity> userFormDataEntities = userFormDataMapper.selectRowsBySql(sqlBuilder.toString());
+
+        // 杩囨护鎸囧畾瀛楁
+        List<Map> maps = expandData(userFormDataEntities, request.getFilterFields());
+        return new FormDataTableVO(maps, total);
+    }
+
+//    @Override
+//    public List<Map> searchAll(QueryFormResultRequest request) {
+//        // 鎷兼帴sql
+//        List<UserFormDataEntity> userFormDataEntities = userFormDataMapper.selectRowsBySql("select * from fm_user_form_data where form_key = '" + request.getFormKey() + "'");
+//        return expandData(userFormDataEntities, null);
+//    }
+
+
+    /**
+     * 灞曞紑鏁版嵁涓轰竴绾�
+     */
+    public List<Map> expandData(List<UserFormDataEntity> userFormDataEntities, String[] filterFields) {
+        return userFormDataEntities.stream().map(item -> {
+            Map<String, Object> processData = item.getOriginalData();
+            Map<String, Object> resultMap = BeanUtil.beanToMap(item);
+            resultMap.remove(UserFormDataEntity.Fields.originalData);
+//            resultMap.put(BaseEntity.Fields.createTime, LocalDateTimeUtil.formatNormal(item.getCreateTime()));
+//            resultMap.put(BaseEntity.Fields.updateTime, LocalDateTimeUtil.formatNormal(item.getUpdateTime()));
+            processData.putAll(resultMap);
+            // 鍙繃婊ゆ寚瀹氬瓧娈�
+            if (filterFields != null) {
+                Map<String, Object> filterMap = MapUtil.newHashMap();
+                for (String filterField : filterFields) {
+                    filterMap.put(filterField, processData.get(filterField));
+                }
+                return filterMap;
+            }
+            return processData;
+        }).collect(Collectors.toList());
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormTemplateCategoryServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormTemplateCategoryServiceImpl.java
new file mode 100644
index 0000000..e77fb94
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormTemplateCategoryServiceImpl.java
@@ -0,0 +1,18 @@
+package com.ltkj.tduck.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.FormTemplateCategoryEntity;
+import com.ltkj.tduck.mapper.FormTemplateCategoryMapper;
+import com.ltkj.tduck.service.FormTemplateCategoryService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 琛ㄥ崟妯℃澘鍒嗙被(FormTemplateType)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2021-01-06 10:51:06
+ */
+@Service
+public class FormTemplateCategoryServiceImpl extends ServiceImpl<FormTemplateCategoryMapper, FormTemplateCategoryEntity> implements FormTemplateCategoryService {
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormThemeServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormThemeServiceImpl.java
new file mode 100644
index 0000000..35ea286
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/FormThemeServiceImpl.java
@@ -0,0 +1,46 @@
+package com.ltkj.tduck.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.FormThemeEntity;
+import com.ltkj.tduck.mapper.FormThemeMapper;
+import com.ltkj.tduck.service.FormThemeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * 琛ㄥ崟涓婚澶栬妯℃澘(FormTheme)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2020-11-23 18:33:56
+ */
+@Service
+@RequiredArgsConstructor
+public class FormThemeServiceImpl extends ServiceImpl<FormThemeMapper, FormThemeEntity> implements FormThemeService {
+
+//    private final FormThemeCategoryMapper formThemeCategoryMapper;
+//
+//    @Override
+//    public List<FormThemeCategoryEntity> listThemeCategories() {
+//        return formThemeCategoryMapper.selectList(null);
+//    }
+//
+//    @Override
+//    public FormThemeCategoryEntity getThemeCategory(Long categoryId) {
+//        return formThemeCategoryMapper.selectById(categoryId);
+//    }
+//
+//    @Override
+//    public Boolean saveThemeCategory(FormThemeCategoryEntity entity) {
+//        return formThemeCategoryMapper.insert(entity) > 0;
+//    }
+//
+//    @Override
+//    public Boolean updateThemeCategory(FormThemeCategoryEntity entity) {
+//        return formThemeCategoryMapper.updateById(entity) > 0;
+//    }
+//
+//    @Override
+//    public Boolean deleteThemeCategory(List<Long> categoryIds) {
+//        return formThemeCategoryMapper.deleteBatchIds(categoryIds) > 0;
+//    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormDataServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormDataServiceImpl.java
new file mode 100644
index 0000000..6cb5bdd
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormDataServiceImpl.java
@@ -0,0 +1,159 @@
+package com.ltkj.tduck.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.map.MapUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.common.utils.ip.AddressUtils;
+import com.ltkj.tduck.constant.CommonConstants;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import com.ltkj.tduck.mapper.UserFormDataMapper;
+import com.ltkj.tduck.request.QueryFormResultRequest;
+import com.ltkj.tduck.service.UserFormDataService;
+import com.ltkj.tduck.service.UserFormItemService;
+import com.ltkj.tduck.utils.CacheUtils;
+import com.ltkj.tduck.utils.FormDataUtils;
+import com.ltkj.tduck.utils.Result;
+import com.ltkj.tduck.vo.FormDataTableVO;
+import com.ltkj.tduck.vo.FormFieldVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static com.ltkj.tduck.constant.FormRedisKeyConstants.FORM_RESULT_NUMBER;
+
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(FormResult)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2020-11-23 14:09:22
+ */
+@Service
+@Slf4j
+@RequiredArgsConstructor
+public class UserFormDataServiceImpl extends ServiceImpl<UserFormDataMapper, UserFormDataEntity> implements UserFormDataService {
+
+    private final UserFormItemService userFormItemService;
+    private final CacheUtils redisUtils;
+    private final FormDataUtils formDataUtils;
+
+
+    @Override
+    @Transactional(rollbackFor = Exception.class)
+    public Map<String, Object> saveFormResult(UserFormDataEntity entity) {
+        HashMap<String, Object> result = MapUtil.newHashMap();
+        String formKey = entity.getFormKey();
+        entity.setSubmitAddress(AddressUtils.getRealAddressByIP(entity.getSubmitRequestIp()));
+        entity.setSerialNumber(redisUtils.incr(StrUtil.format(FORM_RESULT_NUMBER, formKey), CommonConstants.ConstantNumber.ONE));
+        this.save(entity);
+//        formDataUtils.syncSaveFormData(entity);
+        result.put("id", entity.getId());
+        return result;
+    }
+
+
+    /**
+     * 涓嬭浇琛ㄥ崟缁撴灉涓殑闄勪欢
+     *
+     * @param request
+     * @return
+     */
+//    @Override
+//    public Result downloadFormResultFile(QueryFormResultRequest request) {
+//        String uuid = IdUtil.simpleUUID();
+//        List<UserFormItemEntity> userFormItemEntityList = userFormItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, request.getFormKey()).in(UserFormItemEntity::getType, CollUtil.newArrayList(FormItemTypeEnum.UPLOAD.toString(), FormItemTypeEnum.IMAGE_UPLOAD.toString())));
+//        //缁撴灉
+//        List<Map> rows = null;
+//        if (ObjectUtil.isNull(request.getCurrent()) && ObjectUtil.isNull(request.getSize())) {
+//            rows = formDataUtils.searchAll(request);
+//        } else {
+//            FormDataTableVO formDataTableVO = this.listFormDataTable(request);
+//            rows = formDataTableVO.getRows();
+//        }
+//        if (CollectionUtil.isEmpty(rows) || CollectionUtil.isEmpty(userFormItemEntityList)) {
+//            return Result.failed("鏆傛棤鏀堕泦闄勪欢锛屾棤娉曚笅杞�");
+//        }
+//        List<Map> finalRows = rows;
+//        ThreadUtil.execAsync(() -> {
+//            TimeInterval timer = DateUtil.timer();
+//            List<String> paths = new ArrayList<>();
+//            List<InputStream> ins = new ArrayList<>();
+//            try {
+//                finalRows.forEach(result -> {
+//                    int index = 0;
+//                    userFormItemEntityList.forEach(item -> {
+//                        List<UploadResultStruct> uploadResults = JsonUtils.jsonToList(JsonUtils.objToJson(MapUtil.get(result, item.getFormItemId(), List.class)), UploadResultStruct.class);
+//                        if (CollectionUtil.isNotEmpty(uploadResults)) {
+//                            uploadResults.forEach(uFile -> {
+//                                if (StrUtil.isNotBlank(uFile.getUrl())) {
+//                                    paths.add(FileNameUtil.getName(uFile.getUrl()));
+//                                    byte[] bytes = HttpUtil.downloadBytes(uFile.getUrl());
+//                                    ins.add(IoUtil.toStream(bytes));
+//                                }
+//                            });
+//                        }
+//                    });
+//                    AsyncProcessUtils.setProcess(uuid, ++index / finalRows.size());
+//                });
+//                // 鍘嬬缉涓婁紶oss
+//                ByteArrayOutputStream zipOutputStream = new ByteArrayOutputStream();
+//                ZipUtil.zip(zipOutputStream, paths.toArray(new String[]{}), ins.toArray(new InputStream[]{}));
+//                String downloadUrl = OssStorageFactory.getStorageService().upload(zipOutputStream.toByteArray(), StorageUtils.generateFileName("download", ".zip"));
+//                AsyncProcessUtils.setProcess(uuid, downloadUrl);
+//                log.info("export file cost time: {}", timer.interval());
+//            } catch (Exception e) {
+//                log.error("download file", e);
+//            }
+//        });
+//        return Result.success(uuid);
+//    }
+//
+//
+    @Override
+    public FormDataTableVO listFormDataTable(QueryFormResultRequest request) {
+        return formDataUtils.search(request);
+    }
+//
+//
+//    @Override
+//    public Boolean deleteByIds(List<String> dataIdList, String formKey) {
+//        baseMapper.deleteBatchIds(dataIdList);
+//        formDataUtils.asyncDeleteEsDocument(dataIdList, formKey);
+//        return true;
+//    }
+//
+//    @Override
+//    public Boolean updateFormResult(UserFormDataEntity entity) {
+//        UserFormDataEntity dataEntity = this.getById(entity.getId());
+//        dataEntity.setOriginalData(entity.getOriginalData());
+//        dataEntity.setUpdateBy(entity.getUpdateBy());
+//        boolean update = this.updateById(dataEntity);
+//        // 鏌ヨ鏁版嵁 鍚屾鍒癳s 閬垮厤鏁版嵁鍙樼┖琚鐩�
+//        formDataUtils.asyncUpdateEsDocument(dataEntity);
+//        return update;
+//    }
+
+    @Override
+    public Result getFormDataDetails(String dataId) {
+        Map<String, Object> result =new HashMap<>();
+        UserFormDataEntity dataEntity = this.getById(dataId);
+        List<FormFieldVO> formFields = userFormItemService.listFormFields(dataEntity.getFormKey());
+        // 琛ㄥ崟瀛楁
+        result.put("formFields", formFields);
+        // 琛ㄥ崟濉啓鏁版嵁
+        if (ObjectUtil.isNotNull(dataEntity)) {
+            Map<String, Object> originalData = dataEntity.getOriginalData();
+            dataEntity.setOriginalData(null);
+            originalData.putAll(BeanUtil.beanToMap(dataEntity, false, true));
+            result.put("formData", originalData);
+        }
+        return Result.success(result);
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormItemServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormItemServiceImpl.java
new file mode 100644
index 0000000..2e078ec
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormItemServiceImpl.java
@@ -0,0 +1,105 @@
+package com.ltkj.tduck.service.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.util.ObjectUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.UserFormEntity;
+import com.ltkj.tduck.domain.UserFormItemEntity;
+import com.ltkj.tduck.enums.FormItemTypeEnum;
+import com.ltkj.tduck.mapper.UserFormItemMapper;
+import com.ltkj.tduck.service.UserFormItemService;
+import com.ltkj.tduck.service.UserFormService;
+import com.ltkj.tduck.struct.CheckboxSchemaStruct;
+import com.ltkj.tduck.struct.InputResultStruct;
+import com.ltkj.tduck.utils.FormDataUtils;
+import com.ltkj.tduck.vo.FormFieldVO;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+import java.util.Comparator;
+import java.util.List;
+import java.util.stream.Collectors;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(FormItem)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2020-11-19 10:49:18
+ */
+@Service
+@RequiredArgsConstructor
+public class UserFormItemServiceImpl extends ServiceImpl<UserFormItemMapper, UserFormItemEntity> implements UserFormItemService {
+
+
+    private final UserFormService userFormService;
+
+//    @Override
+//    public List<UserFormItemEntity> listByFormKey(String key) {
+//        List<UserFormItemEntity> list = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, key));
+//        list.sort(Comparator.comparing(UserFormItemEntity::getSort));
+//        return list;
+//    }
+//
+    @Override
+    public List<FormFieldVO> listFormFields(String formKey) {
+        List<UserFormItemEntity> itemEntityList = this.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey).eq(UserFormItemEntity::getDisplayType, 0));
+        itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort));
+        // FormFieldVO 澶勭悊浜嗛儴浠界粍浠烽粯璁ゆ樉绀簂abel瀛楁
+        List<FormFieldVO> fields = itemEntityList.stream().map(FormFieldVO::new).collect(Collectors.toList());
+        return fields;
+    }
+
+    @Override
+    public List<FormFieldVO> listAllFormFields(String formKey) {
+        // 鏌ヨ琛ㄥ崟绫诲瀷
+        UserFormEntity userFormEntity = userFormService.getByKey(formKey);
+        List<FormFieldVO> fields = this.listFormFields(formKey);
+        FormDataUtils.addFormDefaultDataField(userFormEntity, fields);
+        return fields;
+    }
+
+    @Override
+    public Long getLastItemSort(String formKey) {
+        List<UserFormItemEntity> formItemEntityPage = baseMapper.selectList(
+                Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey)
+                        .orderByDesc(UserFormItemEntity::getSort));
+
+        // 鍘诲彇绗竴涓厓绱�
+        UserFormItemEntity first = CollUtil.getFirst(formItemEntityPage);
+        return ObjectUtil.isNull(first) ? 0 : first.getSort();
+    }
+
+    @Override
+    public Boolean isSpecialTypeItem(UserFormItemEntity userFormItemEntity) {
+        // 闅忔満缂栧彿
+        if (userFormItemEntity.getType() == FormItemTypeEnum.RANDOM_NUMBER) {
+            return true;
+        }
+        // 涓嶅厑璁搁噸澶�
+        if (userFormItemEntity.getType() == FormItemTypeEnum.INPUT) {
+            InputResultStruct builder = InputResultStruct.builder(userFormItemEntity.getScheme());
+            return builder.isNotRepeat();
+        }
+        // 鍟嗗搧
+        if (userFormItemEntity.getType() == FormItemTypeEnum.GOODS_SELECT) {
+            return true;
+        }
+        // 棰勭害鏃堕棿
+        if (userFormItemEntity.getType() == FormItemTypeEnum.RESERVE_DAY || userFormItemEntity.getType() == FormItemTypeEnum.RESERVE_TIME_RANGE) {
+            return true;
+        }
+        // 鎶曠エ
+        if (userFormItemEntity.getType() == FormItemTypeEnum.CHECKBOX || userFormItemEntity.getType() == FormItemTypeEnum.RADIO || userFormItemEntity.getType() == FormItemTypeEnum.IMAGE_SELECT) {
+            CheckboxSchemaStruct builder = CheckboxSchemaStruct.builder(userFormItemEntity.getScheme());
+            // 鍗曢�夊閫夊甫鍚嶉
+            if (builder.getConfig().getOptions().stream().anyMatch(item -> ObjectUtil.isNotNull(item.getQuotaSetting()))) {
+                return true;
+            }
+            return builder.getConfig().isShowVoteResult();
+        }
+        return false;
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormLogicServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormLogicServiceImpl.java
new file mode 100644
index 0000000..bc3a4ca
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormLogicServiceImpl.java
@@ -0,0 +1,14 @@
+package com.ltkj.tduck.service.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.UserFormLogicEntity;
+import com.ltkj.tduck.mapper.UserFormLogicMapper;
+import com.ltkj.tduck.service.UserFormLogicService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 琛ㄥ崟閫昏緫
+ */
+@Service
+public class UserFormLogicServiceImpl extends ServiceImpl<UserFormLogicMapper, UserFormLogicEntity> implements UserFormLogicService {
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormServiceImpl.java
new file mode 100644
index 0000000..8fa581e
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormServiceImpl.java
@@ -0,0 +1,29 @@
+package com.ltkj.tduck.service.impl;
+
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.UserFormEntity;
+import com.ltkj.tduck.mapper.UserFormMapper;
+import com.ltkj.tduck.service.UserFormService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 琛ㄥ崟涓昏〃(Form)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2020-11-18 18:16:18
+ */
+@Service
+public class UserFormServiceImpl extends ServiceImpl<UserFormMapper, UserFormEntity> implements UserFormService {
+
+    @Override
+    public UserFormEntity getByKey(final String key) {
+        if (StrUtil.isBlank(key)) {
+            return null;
+        }
+        return this.getOne(Wrappers.<UserFormEntity>lambdaQuery().eq(UserFormEntity::getFormKey, key));
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormSettingServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormSettingServiceImpl.java
new file mode 100644
index 0000000..cf23b5b
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormSettingServiceImpl.java
@@ -0,0 +1,194 @@
+package com.ltkj.tduck.service.impl;
+
+import cn.hutool.core.bean.BeanUtil;
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.common.utils.SecurityUtils;
+import com.ltkj.tduck.constant.CommonConstants;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import com.ltkj.tduck.domain.UserFormEntity;
+import com.ltkj.tduck.domain.UserFormSettingEntity;
+import com.ltkj.tduck.enums.FormStatusEnum;
+import com.ltkj.tduck.mapper.UserFormSettingMapper;
+import com.ltkj.tduck.service.UserFormDataService;
+import com.ltkj.tduck.service.UserFormService;
+import com.ltkj.tduck.service.UserFormSettingService;
+import com.ltkj.tduck.struct.FormSettingSchemaStruct;
+import com.ltkj.tduck.utils.Result;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import java.time.LocalTime;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+/**
+ * 琛ㄥ崟琛ㄥ崟椤�(UserFormSetting)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2020-11-30 14:00:53
+ */
+@Service
+@RequiredArgsConstructor
+public class UserFormSettingServiceImpl extends ServiceImpl<UserFormSettingMapper, UserFormSettingEntity> implements UserFormSettingService {
+    private final UserFormService userFormService;
+    private final UserFormDataService userFormDataService;
+
+    @Override
+    public Boolean saveFormSetting(Map<String, Object> params) {
+        String formKey = params.get("formKey").toString();
+        UserFormSettingEntity entity = this.getOne(Wrappers.<UserFormSettingEntity>lambdaQuery().eq(UserFormSettingEntity::getFormKey, formKey));
+        if (ObjectUtil.isNull(entity)) {
+            UserFormSettingEntity setting = new UserFormSettingEntity();
+            setting.setFormKey(formKey);
+            setting.setSettings(params);
+            return this.save(setting);
+        }
+        Map<String, Object> settings = entity.getSettings();
+        settings.putAll(params);
+        entity.setSettings(settings);
+        return this.updateById(entity);
+    }
+
+
+    @Override
+    public UserFormSettingEntity getFormSettingByKey(String formKey) {
+        return this.getOne(Wrappers.<UserFormSettingEntity>lambdaQuery().eq(UserFormSettingEntity::getFormKey, formKey));
+    }
+
+    @Override
+    public FormSettingSchemaStruct getFormSettingSchema(String formKey) {
+        UserFormSettingEntity settingEntity = getFormSettingByKey(formKey);
+        if (ObjectUtil.isNull(settingEntity)) {
+            return null;
+        }
+        return BeanUtil.toBean(settingEntity.getSettings(), FormSettingSchemaStruct.class);
+    }
+
+
+    @Override
+    public Result<Boolean> getUserFormWriteSettingStatus(String formKey, String requestIp, String wxOpenId, Integer type) {
+        UserFormEntity userFormEntity = userFormService.getByKey(formKey);
+        boolean checkPublish = Objects.equals(type, CommonConstants.ConstantNumber.ONE) &&
+                (ObjectUtil.isNull(userFormEntity) || userFormEntity.getStatus() != 2);
+        // 闈炲叕寮�濉啓 涓嶆牎楠屽彂甯冪姸鎬�
+        if (checkPublish) {
+            return Result.success(null, "琛ㄥ崟鏆傛椂鏃犳硶濉啓");
+        }
+        UserFormSettingEntity settingEntity = getFormSettingByKey(formKey);
+        if (ObjectUtil.isNull(settingEntity)) {
+            return Result.success(true);
+        }
+        FormSettingSchemaStruct settingSchemaStruct = BeanUtil.toBean(settingEntity.getSettings(), FormSettingSchemaStruct.class);
+        // 濉啓鏃堕棿闄愬埗
+        boolean writeInterviewTime = isWriteInterviewTime(settingSchemaStruct);
+        if (!writeInterviewTime) {
+            return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getWriteInterviewTimeText(), "涓嶅湪绛旈鏃堕棿鑼冨洿鍐咃紝鏈夐棶棰樿涓庤〃鍗曞彂甯冭�呰仈绯�"));
+        }
+        // 姣忎釜寰俊绛旈娆℃暟闄愬埗
+        if (settingSchemaStruct.isWxWriteCountLimitStatus()) {
+            LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey).eq(UserFormDataEntity::getWxOpenId, wxOpenId);
+            String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getWxWriteCountLimitDateType());
+            wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql);
+            long writeCount = userFormDataService.count(wrapper);
+            if (writeCount >= settingSchemaStruct.getWxWriteCountLimit()) {
+                return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getWxWriteCountLimitText(), "璇ュ井淇″凡缁忔彁浜よ繃鏁版嵁锛屼笉鍙噸澶嶆彁浜わ紝鏈夐棶棰樿涓庤〃鍗曞彂甯冭�呰仈绯�"));
+            }
+        }
+        // 姣忎釜IP绛旈娆℃暟闄愬埗
+        if (settingSchemaStruct.isIpWriteCountLimitStatus()) {
+            LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey).eq(UserFormDataEntity::getSubmitRequestIp, requestIp);
+            String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getIpWriteCountLimitDateType());
+            wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql);
+            long writeCount = userFormDataService.count(wrapper);
+            if (writeCount >= settingSchemaStruct.getIpWriteCountLimit()) {
+                return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getIpWriteCountLimitText(), "璇P宸茬粡鎻愪氦杩囨暟鎹紝涓嶅彲閲嶅鎻愪氦锛屾湁闂璇蜂笌琛ㄥ崟鍙戝竷鑰呰仈绯�"));
+            }
+        }
+        // 鎬荤瓟棰樻鏁伴檺鍒�
+        if (settingSchemaStruct.isTotalWriteCountLimitStatus()) {
+            LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey);
+            String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getTotalWriteCountLimitDateType());
+            wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql);
+            long writeCount = userFormDataService.count(wrapper);
+            if (writeCount >= settingSchemaStruct.getTotalWriteCountLimit()) {
+                return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getTotalWriteCountLimitText(), "璇ヨ〃鍗曟敹闆嗘暟鎹凡缁忚揪鍒颁笂闄愶紝鏈夐棶棰樿涓庤〃鍗曞彂甯冭�呰仈绯�"));
+            }
+        }
+        // 姣忎釜璐﹀彿绛旈娆℃暟闄愬埗
+        if (settingSchemaStruct.isAccountWriteCountLimitStatus()) {
+            LambdaQueryWrapper<UserFormDataEntity> wrapper = Wrappers.<UserFormDataEntity>lambdaQuery().eq(UserFormDataEntity::getFormKey, formKey)
+                    .eq(UserFormDataEntity::getCreateBy, SecurityUtils.getUserId());
+            String rangeTypeSql = FormSettingSchemaStruct.DateRangeType.getDateSql(settingSchemaStruct.getAccountWriteCountLimitDateType());
+            wrapper.apply(StrUtil.isNotBlank(rangeTypeSql), rangeTypeSql);
+            long writeCount = userFormDataService.count(wrapper);
+            if (writeCount >= settingSchemaStruct.getAccountWriteCountLimit()) {
+                return Result.success(null, StrUtil.blankToDefault(settingSchemaStruct.getAccountWriteCountLimitText(), "璇ヨ处鍙峰凡缁忔彁浜よ繃鏁版嵁锛屼笉鍙噸澶嶆彁浜わ紝鏈夐棶棰樿涓庤〃鍗曞彂甯冭�呰仈绯�"));
+            }
+        }
+        return Result.success(true);
+    }
+
+    /**
+     * 鏄惁鍦ㄨ缃殑绛旈鏃堕棿鍐�
+     *
+     * @return true 鍦ㄧ瓟棰樻椂闂村唴
+     */
+    private boolean isWriteInterviewTime(FormSettingSchemaStruct settingSchemaStruct) {
+        // 绛旈鏃堕棿闄愬埗
+        if (settingSchemaStruct.isWriteInterviewTimeStatus()) {
+            // 鏄惁姣忓ぉ鏃堕棿鑼冨洿闄愬埗
+            if (settingSchemaStruct.isWriteInterviewDayTimeStatus()) {
+                // 鏄惁鍦ㄥ厑璁歌闂殑澶╁唴
+                List<String> writeInterviewDateRange = settingSchemaStruct.getWriteInterviewDateRange();
+                if (CollUtil.isEmpty(writeInterviewDateRange) || DateUtil.isIn(DateUtil.date(), DateUtil.parse(writeInterviewDateRange.get(0)), DateUtil.parse(writeInterviewDateRange.get(1)))) {
+                    // 鏄惁鍦ㄥ厑璁歌闂殑灏忔椂鍐�
+                    List<String> writeInterviewTimeRange = settingSchemaStruct.getWriteInterviewTimeRange();
+                    LocalTime now = LocalTime.now();
+                    boolean isRange = CollUtil.isNotEmpty(writeInterviewDateRange) && now.isBefore(LocalTime.parse(writeInterviewTimeRange.get(0))) || now.isAfter(LocalTime.parse(writeInterviewTimeRange.get(1)));
+                    if (isRange) {
+                        return false;
+                    }
+                } else {
+                    return false;
+                }
+            } else {
+                // 鏄惁鍦ㄥ厑璁歌闂殑澶╁唴
+                List<String> writeInterviewDateTimeRange = settingSchemaStruct.getWriteInterviewDateTimeRange();
+                if (CollUtil.isNotEmpty(writeInterviewDateTimeRange) && !DateUtil.isIn(DateUtil.date(), DateUtil.parse(writeInterviewDateTimeRange.get(0)), DateUtil.parse(writeInterviewDateTimeRange.get(1)))) {
+                    return false;
+                }
+            }
+            // 鏄惁鏄瘡鍛ㄥ厑璁歌闂殑鍛ㄥ嚑
+            List<String> writeInterviewTimeWhichDays = settingSchemaStruct.getWriteInterviewTimeWhichDays();
+            if (CollUtil.isNotEmpty(writeInterviewTimeWhichDays)) {
+                // 鑾峰彇浠婂ぉ鏄瘡鍛ㄧ殑绗嚑澶�
+                int day = DateUtil.dayOfWeek(DateUtil.date());
+                return writeInterviewTimeWhichDays.contains(String.valueOf(day));
+            }
+        }
+        return true;
+    }
+
+
+    /**
+     * 鍒犻櫎鍏ㄩ儴鐨勮〃鍗曟暟鎹�
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 鍒犻櫎缁撴灉
+     */
+    @Override
+    @Transactional(rollbackFor = {Exception.class})
+    public Boolean deleteAllSetting(String formKey) {
+        this.remove(Wrappers.<UserFormSettingEntity>lambdaQuery().eq(UserFormSettingEntity::getFormKey, formKey));
+        return true;
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormThemeServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormThemeServiceImpl.java
new file mode 100644
index 0000000..48916e6
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormThemeServiceImpl.java
@@ -0,0 +1,27 @@
+package com.ltkj.tduck.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.UserFormThemeEntity;
+import com.ltkj.tduck.mapper.UserFormThemeMapper;
+import com.ltkj.tduck.service.UserFormThemeService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Service;
+
+/**
+ * 椤圭洰琛ㄥ崟椤�(UserFormTheme)琛ㄦ湇鍔″疄鐜扮被
+ *
+ * @author smalljop
+ * @since 2020-11-25 13:36:32
+ */
+@Service
+@RequiredArgsConstructor
+public class UserFormThemeServiceImpl extends ServiceImpl<UserFormThemeMapper, UserFormThemeEntity> implements UserFormThemeService {
+
+
+    @Override
+    public UserFormThemeEntity getByKey(String key) {
+        UserFormThemeEntity userFormThemeEntity = this.getOne(Wrappers.<UserFormThemeEntity>lambdaQuery().eq(UserFormThemeEntity::getFormKey, key));
+        return userFormThemeEntity;
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormViewCountServiceImpl.java b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormViewCountServiceImpl.java
new file mode 100644
index 0000000..e30b365
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/service/impl/UserFormViewCountServiceImpl.java
@@ -0,0 +1,29 @@
+package com.ltkj.tduck.service.impl;
+
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.ltkj.tduck.domain.UserFormViewCountEntity;
+import com.ltkj.tduck.mapper.UserFormViewCountMapper;
+import com.ltkj.tduck.service.UserFormViewCountService;
+import org.springframework.stereotype.Service;
+
+/**
+ * 鐢ㄦ埛琛ㄥ崟鏌ョ湅娆℃暟Service涓氬姟灞傚鐞�
+ *
+ * @author tduck
+ * @date 2023-04-04 21:29:39
+ */
+@Service
+public class UserFormViewCountServiceImpl extends ServiceImpl<UserFormViewCountMapper, UserFormViewCountEntity> implements UserFormViewCountService {
+
+    @Override
+    public void increment(String formKey) {
+        baseMapper.incrementCount(formKey);
+    }
+
+    @Override
+    public Long count(String formKey) {
+        UserFormViewCountEntity viewCount = baseMapper.selectOne(Wrappers.<UserFormViewCountEntity>lambdaQuery().eq(UserFormViewCountEntity::getFormKey, formKey));
+        return viewCount == null ? 0 : viewCount.getCount();
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/struct/CheckboxSchemaStruct.java b/ltkj-system/src/main/java/com/ltkj/tduck/struct/CheckboxSchemaStruct.java
new file mode 100644
index 0000000..c1529a7
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/struct/CheckboxSchemaStruct.java
@@ -0,0 +1,37 @@
+package com.ltkj.tduck.struct;
+
+import com.ltkj.tduck.utils.JsonUtils;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Map;
+
+/**
+ * @author : smalljop
+ * @description : 閫夐」缁撴瀯
+ * @create :  2021/06/07 16:37
+ **/
+
+@NoArgsConstructor
+@AllArgsConstructor
+@Data
+public class CheckboxSchemaStruct {
+
+    private Config config;
+
+
+
+    @Data
+    public static class Config extends OptionQuotaListStruct{
+        private boolean showVoteResult;
+    }
+
+
+
+
+
+    public static CheckboxSchemaStruct builder(Map<String, Object> params) {
+        return JsonUtils.objToObj(params, CheckboxSchemaStruct.class);
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/struct/FormDataFilterStruct.java b/ltkj-system/src/main/java/com/ltkj/tduck/struct/FormDataFilterStruct.java
new file mode 100644
index 0000000..1295908
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/struct/FormDataFilterStruct.java
@@ -0,0 +1,118 @@
+package com.ltkj.tduck.struct;
+
+import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+
+/**
+ * @author : wangqing
+ * @description : 鏁版嵁杩囨护瀵硅薄缁撴瀯
+ * @create :  2021/10/13 14:49
+ **/
+@Data
+public class FormDataFilterStruct {
+    /**
+     * or and 閫昏緫杩炴帴绗﹀彿
+     */
+    RelEnum rel;
+
+    /**
+     * 杩囨护鏉′欢
+     */
+    List<Condition> conditionList;
+
+    @Getter
+    @AllArgsConstructor
+    public enum QueryMethodEnum {
+        /**
+         * 绛変簬
+         */
+        EQ,
+        /**
+         * 涓嶇瓑浜�
+         */
+        NE,
+        /**
+         * 鍖呭惈
+         */
+        INCLUDE,
+        /**
+         * 涓嶅寘鍚�
+         */
+        NOT_INCLUDE,
+        /**
+         * 涓虹┖
+         */
+        IS_NULL,
+        /**
+         * 涓嶄负绌�
+         */
+        NOT_NULL,
+        /**
+         * ;
+         * 澶т簬
+         */
+        GT,
+        /**
+         * ;
+         * 澶т簬绛変簬
+         */
+        GE,
+        /**
+         * 灏忎簬
+         */
+        LT,
+        /**
+         * 灏忎簬绛変簬
+         */
+        LE,
+        /**
+         * 鑼冨洿
+         */
+        RANGE,
+        /**
+         * 鏃堕棿鑼冨洿
+         */
+        TIME_RANGE;
+
+    }
+
+    /**
+     * 榛樿鍊肩被鍨嬫灇涓�
+     */
+    public enum DefaultValueTypeEnum {
+        /**
+         * 瀛楃涓�
+         */
+        STRING,
+        /***
+         * 鏁扮粍
+         */
+        ARRAY
+    }
+
+
+    /**
+     * 榛樿鍊肩被鍨嬫灇涓�
+     */
+    public enum RelEnum {
+        AND,
+        OR
+    }
+
+    @Data
+    @AllArgsConstructor
+    @NoArgsConstructor
+    // 蹇界暐鍓嶇浼犵殑鏈畾涔夊弬鏁�
+    @JsonIgnoreProperties(ignoreUnknown = true)
+    public static class Condition {
+        private String formItemId;
+        private QueryMethodEnum method;
+        private Object value;
+        private DefaultValueTypeEnum defaultValueType;
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/struct/FormSettingSchemaStruct.java b/ltkj-system/src/main/java/com/ltkj/tduck/struct/FormSettingSchemaStruct.java
new file mode 100644
index 0000000..5f7ef0f
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/struct/FormSettingSchemaStruct.java
@@ -0,0 +1,78 @@
+package com.ltkj.tduck.struct;
+
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+/**
+ * @author : tduck
+ * @description : 璁剧疆缁撴瀯瀹氫箟
+ * @create :  2021/06/07 16:37
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class FormSettingSchemaStruct extends WriteSettingSchemaStruct {
+    /**
+     * 鑷畾涔夋樉绀虹被鍨� 1 绯荤粺榛樿 2 鑷畾涔夐〉闈� 浣跨敤submitShowCustomPageContent鍐呭
+     */
+    private int submitShowType;
+    /**
+     * 鑷畾涔夋樉绀哄唴瀹�
+     */
+    private String submitShowCustomPageContent;
+    private boolean submitJump;
+    private String submitJumpUrl;
+
+    /**
+     * 鏄剧ず鍒嗕韩鍥剧墖
+     */
+    private boolean shareWxImg;
+    /**
+     * 鍒嗕韩鍥剧墖鍦板潃
+     */
+    private String shareWxImgUrl;
+    /**
+     * 鏄剧ず鍒嗕韩鏍囬
+     */
+    private boolean shareWxTitle;
+    /**
+     * 鍒嗕韩鏍囬鍐呭
+     */
+    private String shareWxTitleContent;
+    /**
+     * 寮�鍚垎浜弿杩�
+     */
+    private boolean shareWxDesc;
+    /**
+     * 鍒嗕韩鎻忚堪鍐呭
+     */
+    private String shareWxDescContent;
+
+    /**
+     * 寮�鍚偖浠堕�氱煡
+     */
+    @JsonIgnore
+    private boolean emailNotify;
+    /**
+     * 閭欢閫氱煡璐﹀彿
+     */
+    @JsonIgnore
+    private String newWriteNotifyEmail;
+    @JsonIgnore
+    private boolean wxNotify;
+    @JsonIgnore
+    private String newWriteNotifyWx;
+
+
+    /**
+     * 鍏紑鍥炲
+     */
+    private boolean openReply;
+
+
+
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/struct/InputResultStruct.java b/ltkj-system/src/main/java/com/ltkj/tduck/struct/InputResultStruct.java
new file mode 100644
index 0000000..73c5206
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/struct/InputResultStruct.java
@@ -0,0 +1,29 @@
+package com.ltkj.tduck.struct;
+
+import com.ltkj.tduck.utils.JsonUtils;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.Map;
+
+/**
+ * @author : smalljop
+ * @description : 涓婁紶鏀堕泦缁撴灉
+ * @create :  2021/06/07 16:37
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class InputResultStruct {
+
+    /**
+     * 涓嶅厑璁搁噸澶�
+     */
+    private boolean notRepeat;
+
+
+    public static InputResultStruct builder(Map<String, Object> params) {
+        return JsonUtils.objToObj(params, InputResultStruct.class);
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/struct/OptionQuotaListStruct.java b/ltkj-system/src/main/java/com/ltkj/tduck/struct/OptionQuotaListStruct.java
new file mode 100644
index 0000000..4ada211
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/struct/OptionQuotaListStruct.java
@@ -0,0 +1,52 @@
+package com.ltkj.tduck.struct;
+
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author : tduck
+ * @description :
+ * @create :  2022/09/26 16:14
+ **/
+@Data
+public class OptionQuotaListStruct {
+    private List<Option> options;
+
+
+    /**
+     * 鍓╀綑鍚嶉涓�0鏃讹紝鏄剧ず鏂囨
+     */
+    private String quotaBlankWarning;
+
+
+    /**
+     * 鍚嶉閲嶇疆
+     */
+    private String quotaCycleRule;
+
+
+    public enum QuotaCycleRule {
+        /**
+         * 涓嶉噸缃�
+         */
+        FIXED,
+        /**
+         * 姣忓ぉ
+         */
+        PER_DAY,
+        /**
+         * 姣忓懆
+         */
+        PER_WEEK;
+    }
+
+
+    @Data
+    public static class Option {
+        private String label;
+        private String value;
+        private Integer quotaSetting;
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/struct/WriteSettingSchemaStruct.java b/ltkj-system/src/main/java/com/ltkj/tduck/struct/WriteSettingSchemaStruct.java
new file mode 100644
index 0000000..692a84a
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/struct/WriteSettingSchemaStruct.java
@@ -0,0 +1,239 @@
+package com.ltkj.tduck.struct;
+
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.Getter;
+import lombok.NoArgsConstructor;
+
+import java.util.Date;
+import java.util.List;
+
+/**
+ * @author : tduck
+ * @description : 璁剧疆缁撴瀯瀹氫箟  @JsonIgnore 涓嶇粰鍓嶇杩斿洖鐨勫瓧娈垫坊鍔犺繖涓�
+ * @create :  2021/06/07 16:37
+ **/
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class WriteSettingSchemaStruct {
+
+    /**
+     * 浠呭湪寰俊濉啓
+     */
+    private boolean onlyWxWrite;
+    /**
+     * 璁板綍寰俊鐢ㄦ埛淇℃伅
+     */
+    private boolean recordWxUser;
+    /**
+     * 鏈湴淇濆瓨鏈彁浜ゆ暟鎹�
+     */
+    private boolean saveSubmitStatus;
+    /**
+     * 鏈湴淇濆瓨鏈彁浜ゆ暟鎹�
+     */
+    private boolean saveNotSubmitStatus;
+    /**
+     * 寮�鍚瘑鐮佸~鍐�
+     */
+    private boolean passwordWriteStatus;
+    /**
+     * 濉啓瀵嗙爜
+     */
+    @JsonIgnore
+    private String writePassword;
+    /**
+     * 寮�鍚瘡涓井淇$瓟棰樻鏁伴檺鍒�
+     */
+    @JsonIgnore
+    private boolean wxWriteCountLimitStatus;
+    /**
+     * 姣忎釜寰俊绛旈娆℃暟闄愬埗娆℃暟
+     */
+    @JsonIgnore
+    private int wxWriteCountLimit = 1;
+    /**
+     * 寮�鍚瘡涓井淇$瓟棰樻椂闂撮檺鍒剁被鍨� 鍏蜂綋鏌ョ湅DateRangeTypeEnum
+     */
+    @JsonIgnore
+    private int wxWriteCountLimitDateType = 1;
+    /**
+     * 寮�鍚瘡涓井淇$瓟棰樻椂闂撮檺鍒舵樉绀烘枃妗�
+     */
+    @JsonIgnore
+    private String wxWriteCountLimitText;
+    /**
+     * 姣忎釜IP绛旈娆℃暟闄愬埗
+     */
+    @JsonIgnore
+    private boolean ipWriteCountLimitStatus;
+    /**
+     * 姣忎釜IP绛旈娆℃暟闄愬埗娆℃暟
+     */
+    @JsonIgnore
+    private int ipWriteCountLimit = 1;
+    /**
+     * 寮�鍚瘡涓狪P绛旈鏃堕棿闄愬埗绫诲瀷 鍏蜂綋鏌ョ湅DateRangeTypeEnum
+     */
+    @JsonIgnore
+    private int ipWriteCountLimitDateType = 1;
+    /**
+     * 寮�鍚瘡涓狪P绛旈鏃堕棿闄愬埗鏄剧ず鏂囨
+     */
+    @JsonIgnore
+    private String ipWriteCountLimitText;
+
+
+    /**
+     * 姣忎釜璐﹀彿绛旈闄愬埗
+     */
+    @JsonIgnore
+    private boolean accountWriteCountLimitStatus;
+    /**
+     * 姣忎釜IP绛旈娆℃暟闄愬埗娆℃暟
+     */
+    @JsonIgnore
+    private int accountWriteCountLimit = 1;
+    /**
+     * 寮�鍚瘡涓处鍙风瓟棰樻椂闂撮檺鍒剁被鍨� 鍏蜂綋鏌ョ湅DateRangeTypeEnum
+     */
+    @JsonIgnore
+    private int accountWriteCountLimitDateType = 1;
+    /**
+     * 寮�鍚瘡涓处鍙风瓟棰樻椂闂撮檺鍒舵樉绀烘枃妗�
+     */
+    @JsonIgnore
+    private String accountWriteCountLimitText;
+
+
+    /**
+     * 姣忎釜璁惧绛旈闄愬埗
+     */
+    private boolean deviceWriteCountLimitStatus;
+    /**
+     * 姣忎釜璁惧绛旈娆℃暟闄愬埗娆℃暟
+     */
+    private int deviceWriteCountLimit = 1;
+
+    /**
+     * 姣忎釜璁惧绛旈鏂囨
+     */
+    private String deviceWriteCountLimitText;
+
+
+    /**
+     * 绱绛旈鏁伴噺
+     */
+    @JsonIgnore
+    private boolean totalWriteCountLimitStatus;
+    /**
+     * 娆℃暟
+     */
+    @JsonIgnore
+    private int totalWriteCountLimit = 1;
+    /**
+     * 绱绛旈鏃ユ湡鑼冨洿绫诲瀷
+     */
+    @JsonIgnore
+    private int totalWriteCountLimitDateType = 1;
+    /**
+     * 绱绛旈鏃ユ湡鑼冨洿鏄剧ず鏂囨
+     */
+    @JsonIgnore
+    private String totalWriteCountLimitText;
+    /**
+     * 寮�鍚瓟棰樻椂闂撮檺鍒�
+     */
+    @JsonIgnore
+    private boolean writeInterviewTimeStatus;
+    /**
+     * 璁块棶鏃堕棿鏄惁鏄竴澶╁唴鐨勬煇浜涘皬鏃�
+     */
+    @JsonIgnore
+    private boolean writeInterviewDayTimeStatus;
+    /**
+     * 鍏佽璁块棶璁块棶鏃堕棿鑼冨洿
+     */
+    @JsonIgnore
+    private List<String> writeInterviewDateTimeRange;
+    /**
+     * 鍏佽璁块棶璁块棶鏃ユ湡鑼冨洿
+     */
+    @JsonIgnore
+    private List<String> writeInterviewDateRange;
+    /**
+     * 鍏佽璁块棶璁块棶鏃堕棿鑼冨洿
+     */
+    @JsonIgnore
+    private List<String> writeInterviewTimeRange;
+    /**
+     * 鍏佽璁块棶璁块棶鏃堕棿鑼冨洿鏄剧ず鏂囨
+     */
+    @JsonIgnore
+    private List<String> writeInterviewTimeWhichDays;
+    /**
+     * 涓嶅厑璁歌闂闂椂闂磋寖鍥存樉绀烘枃妗�
+     */
+    @JsonIgnore
+    private String writeInterviewTimeText;
+
+
+
+
+
+    @AllArgsConstructor
+    public static enum DateRangeType {
+        /**
+         * 鎬诲叡
+         */
+        SUM(1),
+        /**
+         * 姣忓ぉ
+         */
+        DAY(2),
+        /**
+         * 姣忓懆
+         */
+        WEEK(3),
+        /**
+         * 姣忔湀
+         */
+        MONTH(4);
+        @Getter
+        private final int value;
+
+
+        /**
+         * 鑾峰彇瀵瑰簲鐨勬棩鏈熻寖鍥寸被鍨�
+         *
+         * @param value 鍊�
+         * @return 鏃ユ湡鑼冨洿绫诲瀷sql
+         */
+        public static String getDateSql(int value) {
+            Date now = new Date();
+            String sql = " create_time>='{}' and create_time<='{}'";
+            for (DateRangeType type : DateRangeType.values()) {
+                if (type.getValue() == value) {
+                    switch (type) {
+                        case DAY:
+                            return StrUtil.format(sql, DateUtil.beginOfDay(now), DateUtil.endOfDay(now));
+                        case WEEK:
+                            return StrUtil.format(sql, DateUtil.beginOfWeek(now), DateUtil.endOfWeek(now));
+                        case MONTH:
+                            return StrUtil.format(sql, DateUtil.beginOfMonth(now), DateUtil.endOfMonth(now));
+                        default:
+                            return "";
+                    }
+                }
+            }
+            throw new IllegalArgumentException("涓嶆敮鎸佺殑鏃ユ湡鑼冨洿绫诲瀷");
+        }
+
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/CacheUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/CacheUtils.java
new file mode 100644
index 0000000..7f5c037
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/CacheUtils.java
@@ -0,0 +1,133 @@
+package com.ltkj.tduck.utils;
+
+import cn.hutool.core.convert.Convert;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.compress.utils.Lists;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.cache.Cache;
+import org.springframework.cache.annotation.EnableCaching;
+import org.springframework.cache.ehcache.EhCacheCacheManager;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author : tduck
+ * @description : 鍩轰簬ehcache瀹炵幇
+ * @create :  2022/01/06 10:40
+ **/
+@Component
+@Slf4j
+@EnableCaching
+public class CacheUtils {
+    private final String ETERNAL_CACHE_NAME = "eternal_cache";
+    private final String TEMP_CACHE_NAME = "temp_cache";
+    @Autowired
+    private EhCacheCacheManager cacheManager;
+
+    /**
+     * 淇濆瓨鍒癈ache
+     */
+    public void save(String key, String value) {
+        cacheManager.getCache(ETERNAL_CACHE_NAME).put(key, value);
+    }
+
+    /**
+     * 鑾峰彇
+     *
+     * @param key
+     */
+    public String get(String key) {
+        Cache.ValueWrapper valueWrapper = cacheManager.getCache(ETERNAL_CACHE_NAME).get(key);
+        if (ObjectUtil.isNotNull(valueWrapper) && ObjectUtil.isNotNull(valueWrapper.get())) {
+            return valueWrapper.get().toString();
+        }
+        return null;
+    }
+
+
+    /**
+     * 鑷
+     *
+     * @param key
+     * @param number
+     * @return
+     */
+    public Long incr(String key, Integer number) {
+        String v = get(key);
+        if (StrUtil.isBlank(v)) {
+            v = "0";
+        }
+        long finalValue = Convert.toLong(v) + number;
+        save(key, String.valueOf(finalValue));
+        return finalValue;
+    }
+
+
+    /**
+     * 娣诲姞鍒伴泦鍚堢紦瀛�
+     *
+     * @param key
+     * @param value
+     */
+    public void addList(String key, Object value) {
+        List coll = this.getList(key, Object.class);
+        coll.add(value);
+        cacheManager.getCache(TEMP_CACHE_NAME).put(key, JsonUtils.objToJson(coll));
+    }
+
+
+    /**
+     * 浠庨泦鍚堜腑绉婚櫎
+     *
+     * @param key
+     * @param value
+     */
+    public void removeList(String key, Object value) {
+        List coll = this.getList(key, Object.class);
+        coll.remove(value);
+        cacheManager.getCache(TEMP_CACHE_NAME).put(key, JsonUtils.objToJson(coll));
+    }
+
+    /**
+     * 鑾峰彇闆嗗悎
+     *
+     * @param key
+     */
+    public List getList(String key, Class classz) {
+        String v = get(key);
+        if (ObjectUtil.isNotNull(v)) {
+            return JsonUtils.jsonToList(v, classz.getClass());
+        }
+        return Lists.newArrayList();
+    }
+
+
+    /**
+     * 涓存椂淇濆瓨 榛樿5min
+     */
+    public void tempSave(String key, String value) {
+        cacheManager.getCache(TEMP_CACHE_NAME).put(key, value);
+    }
+
+    /**
+     * 鑾峰彇涓存椂瀛樺偍鍙橀噺
+     *
+     * @param key
+     */
+    public String getTemp(String key) {
+        Cache.ValueWrapper valueWrapper = cacheManager.getCache(TEMP_CACHE_NAME).get(key);
+        if (ObjectUtil.isNotNull(valueWrapper) && ObjectUtil.isNotNull(valueWrapper.get())) {
+            return valueWrapper.get().toString();
+        }
+        return null;
+    }
+
+    public void removeTemp(String key) {
+        cacheManager.getCache(TEMP_CACHE_NAME).evict(key);
+    }
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/FormDataUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/FormDataUtils.java
new file mode 100644
index 0000000..b8a7ede
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/FormDataUtils.java
@@ -0,0 +1,144 @@
+package com.ltkj.tduck.utils;
+
+import cn.hutool.core.collection.CollUtil;
+import com.ltkj.tduck.domain.SysBaseEntity;
+import com.ltkj.tduck.domain.TBaseEntity;
+import com.ltkj.tduck.domain.UserFormDataEntity;
+import com.ltkj.tduck.domain.UserFormEntity;
+import com.ltkj.tduck.enums.FormItemTypeEnum;
+import com.ltkj.tduck.request.QueryFormResultRequest;
+import com.ltkj.tduck.service.data.FormDataBaseService;
+import com.ltkj.tduck.vo.FormDataTableVO;
+import com.ltkj.tduck.vo.FormFieldVO;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Component;
+
+import java.util.List;
+
+/**
+ * @author : tduck
+ * @description : 琛ㄥ崟鏀堕泦缁撴灉宸ュ叿绫�
+ * @create :  2021/08/18 18:17
+ **/
+@Slf4j
+@Component
+@RequiredArgsConstructor
+public class FormDataUtils {
+
+
+    /**
+     * 鐗规畩瀛楁 浼氬鍑轰竴涓獂xx label瀛楁瀛樻斁鏄剧ず鍊� 榛樿瀛楁瀛樻斁鍘熷鍊�
+     */
+    public static final List<FormItemTypeEnum> specialFields = CollUtil.newArrayList(FormItemTypeEnum.SELECT, FormItemTypeEnum.IMAGE_SELECT, FormItemTypeEnum.CHECKBOX, FormItemTypeEnum.RADIO, FormItemTypeEnum.CASCADER);
+
+    private final static String FIELD_USER_TYPE = "USER";
+
+    private final FormDataBaseService formDataBaseService;
+
+    /**
+     * 娣诲姞琛ㄥ崟鍩虹鏁版嵁瀛楁
+     * 鎵�鏈夎〃鍗曢兘鍖呭惈鐨勫瓧娈�
+     */
+    public static void addFormBaseDataField(List<FormFieldVO> fields) {
+        fields.add(new FormFieldVO(UserFormDataEntity.Fields.serialNumber, "鎻愪氦搴忓彿", UserFormDataEntity.Fields.serialNumber));
+        fields.add(new FormFieldVO(UserFormDataEntity.Fields.extValue, "鎵╁睍瀛楁", FormItemTypeEnum.INPUT.toString()));
+        fields.add(new FormFieldVO(SysBaseEntity.Fields.updateBy, "淇敼鐢ㄦ埛", FIELD_USER_TYPE));
+        fields.add(new FormFieldVO(SysBaseEntity.Fields.createBy, "鎻愪氦鐢ㄦ埛", FIELD_USER_TYPE));
+        fields.add(new FormFieldVO(TBaseEntity.Fields.createTime, "鎻愪氦鏃堕棿", FormItemTypeEnum.DATE.toString()));
+        fields.add(new FormFieldVO(TBaseEntity.Fields.updateTime, "淇敼鏃堕棿", FormItemTypeEnum.DATE.toString()));
+
+    }
+
+
+    /**
+     * 娣诲姞绯荤粺榛樿瀛楁
+     */
+    public static void addFormDefaultDataField(UserFormEntity entity, List<FormFieldVO> fields) {
+        addFormBaseDataField(fields);
+    }
+
+
+    /***
+     * 琛ㄥ崟瀛楁鍊兼槸鍚﹀瓨鍦�
+     * @param formKey 琛ㄥ崟key
+     * @param formItemId 琛ㄥ崟瀛楁id
+     * @param value 瀛楁鍊�
+     */
+//    public Boolean valueExist(String formKey, String formItemId, Object value) {
+//        return formDataBaseService.valueExist(formKey, formItemId, value);
+//    }
+
+
+    /**
+     * 鐗规畩瀛楁娣诲姞澶嶅悎瀛楁
+     */
+//    public List<String> concatSpecialField(List<String> fields) {
+//        List<String> newFields = CollUtil.newArrayList("id");
+//        if (CollUtil.isEmpty(fields)) {
+//            return newFields;
+//        }
+//        fields.forEach(field -> {
+//            newFields.add(field);
+//            boolean isSpecialField = StrUtil.startWithAny(field, specialFields.stream().map(item -> item.toString().toLowerCase()).collect(Collectors.joining(",")));
+//            if (isSpecialField) {
+//                newFields.add(field + "label");
+//            }
+//        });
+//        return newFields;
+//    }
+
+
+    /**
+     * 淇濆瓨鏁版嵁鍒板叾浠栨暟鎹簱 姣斿es MonggDB绛� 鐢ㄦ潵鎵╁睍鏌ヨ 浣滄姤琛ㄧ瓑
+     */
+//    public Boolean syncSaveFormData(UserFormDataEntity result) {
+//        return formDataBaseService.syncSaveData(result);
+//    }
+
+
+    /**
+     * 鏇存柊鏂囨。
+     *
+     * @param result
+     */
+//    public void asyncUpdateEsDocument(UserFormDataEntity result) {
+//        formDataBaseService.asyncUpdateData(result);
+//    }
+
+    /**
+     * 鍒犻櫎绱㈠紩鏂囨。
+     *
+     * @param idList  doc Id
+     * @param formKey index
+     */
+//    public void asyncDeleteEsDocument(List<String> idList, String formKey) {
+//        formDataBaseService.asyncDeleteData(idList, formKey);
+//    }
+
+
+    /**
+     * 鏌ヨ琛ㄥ崟鍒嗛〉鏁版嵁
+     *
+     * @param request 鏌ヨ鍙傛暟
+     * @return 琛ㄥ崟鍒嗛〉鏁版嵁
+     */
+    public FormDataTableVO search(QueryFormResultRequest request) {
+        return formDataBaseService.search(request);
+    }
+
+    /**
+     * 鍏ㄩ儴鏁版嵁
+     *
+     * @param request 璇锋眰
+     * @return 琛ㄥ崟鏁版嵁
+     */
+//    public List<Map> searchAll(QueryFormResultRequest request) {
+//        return formDataBaseService.searchAll(request);
+//    }
+
+
+
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/HtmlUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/HtmlUtils.java
new file mode 100644
index 0000000..63d3c7b
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/HtmlUtils.java
@@ -0,0 +1,20 @@
+package com.ltkj.tduck.utils;
+
+import cn.hutool.http.HtmlUtil;
+import lombok.experimental.UtilityClass;
+
+@UtilityClass
+public class HtmlUtils extends HtmlUtil {
+
+
+    /**
+     * 娓呴櫎鏍囩 杩樺師杞箟鏂囨湰
+     * @param content
+     * @return
+     */
+    public static String cleanHtmlTag(String content) {
+        // 娓呴櫎HTML鏍囩鍜岀┖鏍� html缂栫爜瑙g爜
+        return HtmlUtil.unescape(content).replaceAll("(<[^<]*?>)|(<[\\s]*?/[^<]*?>)|(<[^<]*?/[\\s]*?>)", "").replaceAll(NBSP, "");
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/IDictEnum.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/IDictEnum.java
new file mode 100644
index 0000000..05271d0
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/IDictEnum.java
@@ -0,0 +1,43 @@
+package com.ltkj.tduck.utils;
+
+import com.baomidou.mybatisplus.annotation.IEnum;
+
+import java.io.Serializable;
+
+/**
+ * @author : wangqing
+ * @description : 瀛楀吀鏋氫妇鍩虹鎺ュ彛
+ * 缁ф壙璇ユ帴鍙d細鍦╦ackson榛樿澧炲己鏄剧ず瀛楁
+ * @create :  2021/12/21 10:19
+ **/
+public interface IDictEnum<T extends Serializable> extends IEnum<T> {
+
+    static <T extends IDictEnum> T getInstance(Class<T> clazz, String code) {
+        T[] constants = clazz.getEnumConstants();
+
+        for (T t : constants) {
+            if (String.valueOf(t.getValue()).equals(code)) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * 鏁版嵁搴撲腑瀛樺偍鐨勫��
+     *
+     * @return 鏁版嵁搴撲腑瀛樺偍鐨勫��
+     */
+    @Override
+    T getValue();
+
+
+    /**
+     * 鑾峰彇鏋氫妇鎻忚堪
+     *
+     * @return 鎻忚堪
+     */
+    String getDesc();
+
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/JsonUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/JsonUtils.java
new file mode 100644
index 0000000..b632864
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/JsonUtils.java
@@ -0,0 +1,276 @@
+package com.ltkj.tduck.utils;
+
+import cn.hutool.core.util.StrUtil;
+import com.fasterxml.jackson.annotation.JsonInclude;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.*;
+import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author smalljop
+ * @description: json宸ュ叿绫� 浣跨敤jackson
+ * @create: 2018-10-23 10:21
+ **/
+public class JsonUtils {
+
+    private final static ObjectMapper objectMapper = new ObjectMapper();
+
+    static {
+        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
+        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+        objectMapper.registerModule(new JavaTimeModule());
+    }
+
+    private JsonUtils() {
+
+    }
+
+
+    /**
+     * 鑾峰彇objectMapper瀹炰緥
+     */
+    public static ObjectMapper getInstance() {
+        return objectMapper;
+    }
+
+    /**
+     * javaBean銆佸垪琛ㄦ暟缁勮浆鎹负json瀛楃涓�
+     */
+    public static String objToJson(Object obj) {
+        try {
+            return objectMapper.writeValueAsString(obj);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    /**
+     * javaBean銆佸垪琛ㄦ暟缁勮浆鎹负json瀛楃涓�,蹇界暐绌哄��
+     */
+    public static String objToJsonIgnoreNull(Object obj) throws Exception {
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        return mapper.writeValueAsString(obj);
+    }
+
+    /**
+     * json 杞璞�
+     */
+    public static <T> T jsonToObj(String jsonString, Class<T> clazz) {
+        if (StrUtil.isBlank(jsonString)) {
+            return null;
+        }
+        //鍏佽鍑虹幇鍗曞紩鍙�
+        objectMapper.configure(JsonParser.Feature.ALLOW_SINGLE_QUOTES, true);
+        //鎺ュ彈鍙湁涓�涓厓绱犵殑鏁扮粍鐨勫弽搴忓垪鍖�
+        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
+        try {
+            return objectMapper.readValue(jsonString, clazz);
+        } catch (IOException e) {
+            throw new RuntimeException(e.getMessage());
+        }
+    }
+
+    /**
+     * json瀛楃涓茶浆鎹负map
+     */
+    public static <T> Map<String, Object> jsonToMap(String jsonString) {
+        if (StrUtil.isBlank(jsonString)) {
+            return null;
+        }
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        try {
+            return mapper.readValue(jsonString, Map.class);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+            return null;
+        }
+    }
+
+
+    public static <T> JsonNode jsonToJsonNode(String jsonString) {
+        if (StrUtil.isBlank(jsonString)) {
+            return null;
+        }
+        ObjectMapper mapper = new ObjectMapper();
+        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
+        try {
+            return mapper.readValue(jsonString, JsonNode.class);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+            return null;
+        }
+
+    }
+
+
+    /**
+     * json瀛楃涓茶浆鎹负map
+     */
+    public static <T> Map<String, T> jsonToMap(String jsonString, Class<T> clazz) throws Exception {
+        Map<String, Map<String, Object>> map = (Map<String, Map<String, Object>>) objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() {
+        });
+        Map<String, T> result = new HashMap<String, T>();
+        for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
+            result.put(entry.getKey(), mapToObj(entry.getValue(), clazz));
+        }
+        return result;
+    }
+
+    /**
+     * 娣卞害杞崲json鎴恗ap
+     *
+     * @param json
+     * @return
+     */
+    public static Map<String, Object> jsonToMapDeeply(String json) throws Exception {
+        return jsonToMapRecursion(json, objectMapper);
+    }
+
+    /**
+     * 鎶妀son瑙f瀽鎴恖ist锛屽鏋渓ist鍐呴儴鐨勫厓绱犲瓨鍦╦sonString锛岀户缁В鏋�
+     *
+     * @param json
+     * @param mapper 瑙f瀽宸ュ叿
+     * @return
+     * @throws Exception
+     */
+    private static List<Object> jsonToListRecursion(String json, ObjectMapper mapper) throws Exception {
+        if (json == null) {
+            return null;
+        }
+
+        List<Object> list = mapper.readValue(json, List.class);
+
+        for (Object obj : list) {
+            if (obj != null && obj instanceof String) {
+                String str = (String) obj;
+                if (str.startsWith("[")) {
+                    obj = jsonToListRecursion(str, mapper);
+                } else if (obj.toString().startsWith("{")) {
+                    obj = jsonToMapRecursion(str, mapper);
+                }
+            }
+        }
+
+        return list;
+    }
+
+    /**
+     * 鎶妀son瑙f瀽鎴恗ap锛屽鏋渕ap鍐呴儴鐨剉alue瀛樺湪jsonString锛岀户缁В鏋�
+     *
+     * @param json
+     * @param mapper
+     * @return
+     * @throws Exception
+     */
+    private static Map<String, Object> jsonToMapRecursion(String json, ObjectMapper mapper) throws Exception {
+        if (json == null) {
+            return null;
+        }
+
+        Map<String, Object> map = mapper.readValue(json, Map.class);
+
+        for (Map.Entry<String, Object> entry : map.entrySet()) {
+            Object obj = entry.getValue();
+            if (obj != null && obj instanceof String) {
+                String str = ((String) obj);
+
+                if (str.startsWith("[")) {
+                    List<?> list = jsonToListRecursion(str, mapper);
+                    map.put(entry.getKey(), list);
+                } else if (str.startsWith("{")) {
+                    Map<String, Object> mapRecursion = jsonToMapRecursion(str, mapper);
+                    map.put(entry.getKey(), mapRecursion);
+                }
+            }
+        }
+
+        return map;
+    }
+
+    /**
+     * 涓巎avaBean json鏁扮粍瀛楃涓茶浆鎹负鍒楄〃
+     */
+    public static <T> List<T> jsonToList(String jsonArrayStr, Class<T> clazz) {
+
+        JavaType javaType = getCollectionType(ArrayList.class, clazz);
+        List<T> lst = null;
+        try {
+            lst = objectMapper.readValue(jsonArrayStr, javaType);
+        } catch (JsonProcessingException e) {
+            e.printStackTrace();
+        }
+        return lst;
+    }
+
+
+    /**
+     * 鑾峰彇娉涘瀷鐨凜ollection Type
+     *
+     * @param collectionClass 娉涘瀷鐨凜ollection
+     * @param elementClasses  鍏冪礌绫�
+     * @return JavaType Java绫诲瀷
+     * @since 1.0
+     */
+    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
+        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
+    }
+
+
+    /**
+     * map  杞琂avaBean
+     */
+    public static <T> T mapToObj(Map map, Class<T> clazz) {
+        return objectMapper.convertValue(map, clazz);
+    }
+
+    /**
+     * map 杞琷son
+     *
+     * @param map
+     * @return
+     */
+    public static String mapToJson(Map map) {
+        try {
+            return objectMapper.writeValueAsString(map);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return "";
+    }
+
+    /**
+     * map  杞琂avaBean
+     */
+    public static <T> T objToObj(Object obj, Class<T> clazz) {
+        return objectMapper.convertValue(obj, clazz);
+    }
+
+
+    /**
+     * 鏄惁鏄痡son鏍煎紡
+     */
+    public static boolean isJson(String json) {
+        try {
+            if(StrUtil.isBlank(json)){
+                return false;
+            }
+            objectMapper.readTree(json);
+            return true;
+        } catch (IOException e) {
+            return false;
+        }
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/LongToStringSerializer.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/LongToStringSerializer.java
new file mode 100644
index 0000000..313b73d
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/LongToStringSerializer.java
@@ -0,0 +1,34 @@
+package com.ltkj.tduck.utils;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.SerializerProvider;
+
+import java.io.IOException;
+
+/**
+ * @author : wangqing
+ * @description : Long杞瑂tring 閬垮厤杩斿洖鍓嶇涓㈠け绮惧害
+ * @create :  2022/03/10 15:07
+ **/
+
+public class LongToStringSerializer extends JsonSerializer<Long> {
+
+
+    /**
+     * Method that can be called to ask implementation to serialize
+     * values of type this serializer handles.
+     *
+     * @param value       Value to serialize; can <b>not</b> be null.
+     * @param gen         Generator used to output resulting Json content
+     * @param serializers Provider that can be used to get serializers for
+     */
+    @Override
+    public void serialize(Long value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
+        if (value != null && value.toString().length() > 16) {
+            gen.writeString(value.toString());
+        } else {
+            gen.writeNumber(value);
+        }
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/Result.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/Result.java
new file mode 100644
index 0000000..5596462
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/Result.java
@@ -0,0 +1,89 @@
+package com.ltkj.tduck.utils;
+
+import cn.hutool.core.util.ObjectUtil;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import com.ltkj.tduck.constant.ResponseCodeConstants;
+import lombok.*;
+import lombok.experimental.Accessors;
+
+import java.io.Serializable;
+
+/**
+ * 鍝嶅簲淇℃伅涓讳綋
+ *
+ * @param <T>
+ * @author smalljop
+ */
+@ToString
+@NoArgsConstructor
+@AllArgsConstructor
+@Accessors(chain = true)
+//@Schema(description = "鍝嶅簲淇℃伅涓讳綋")
+public class Result<T> implements Serializable {
+    private static final long serialVersionUID = 1L;
+
+    @Getter
+    @Setter
+//    @Schema(description = "杩斿洖鏍囪锛氭垚鍔熸爣璁�=200锛屽け璐ユ爣璁�=500")
+    private int code = ResponseCodeConstants.SUCCESS;
+
+    @Getter
+    @Setter
+//    @Schema(description = "杩斿洖淇℃伅")
+    private String msg;
+
+
+    @Getter
+    @Setter
+//    @Schema(description = "鏁版嵁")
+    private T data;
+
+    public static <T> Result<T> success() {
+        return restResult(null, ResponseCodeConstants.SUCCESS, null);
+    }
+
+    public static <T> Result<T> success(T data) {
+        return restResult(data, ResponseCodeConstants.SUCCESS, null);
+    }
+
+    public static <T> Result<T> success(T data, String msg) {
+        return restResult(data, ResponseCodeConstants.SUCCESS, msg);
+    }
+
+    public static <T> Result<T> isSuccess(boolean flag) {
+        return flag ? success() : failed();
+    }
+
+    public static <T> Result<T> failed() {
+        return restResult(null, ResponseCodeConstants.FAIL, null);
+    }
+
+
+    public static <T> Result<T> failed(int code, String msg) {
+        return restResult(null, code, msg);
+    }
+
+    public static <T> Result<T> failed(String msg) {
+        return restResult(null, ResponseCodeConstants.FAIL, msg);
+    }
+
+    public static <T> Result<T> failed(String msg, T data) {
+        return restResult(data, ResponseCodeConstants.FAIL, msg);
+    }
+
+
+    public static <T> Result<T> restResult(T data, int code, String msg) {
+        Result<T> apiResult = new Result<>();
+        apiResult.setCode(code);
+        apiResult.setData(data);
+        apiResult.setMsg(msg);
+        return apiResult;
+    }
+
+
+    @JsonIgnore
+    public Boolean isDataNull() {
+        return ObjectUtil.isNull(data);
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/ShortIdUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/ShortIdUtils.java
new file mode 100644
index 0000000..c44654e
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/ShortIdUtils.java
@@ -0,0 +1,41 @@
+package com.ltkj.tduck.utils;
+
+import cn.hutool.core.util.RandomUtil;
+import lombok.experimental.UtilityClass;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * 鐭璉d宸ュ叿绫�
+ */
+@UtilityClass
+public class ShortIdUtils {
+
+    /**
+     * 榛樿闅忔満瀛楁瘝琛紝浣跨敤URL瀹夊叏鐨凚ase64瀛楃
+     */
+    private static final char[] DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
+
+
+    /**
+     * 鐢熸垚8浣嶉暱搴d
+     *
+     * @return
+     */
+    public String genId() {
+//        return NanoId.randomNanoId(null, DEFAULT_ALPHABET, 8);
+        return RandomUtil.randomString(8);
+    }
+
+    public static void main(String[] args) {
+        Map<Object, Object> of = new HashMap<>();
+        for (int i = 0; i < 100000 ;i++) {
+            String s = genId();
+            Object put = of.put(s, "1");
+            if (null != put) {
+                System.out.println(s);
+            }
+        }
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/SortUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/SortUtils.java
new file mode 100644
index 0000000..c59f3ce
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/SortUtils.java
@@ -0,0 +1,109 @@
+package com.ltkj.tduck.utils;
+
+
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.ltkj.tduck.constant.FormRedisKeyConstants;
+import com.ltkj.tduck.domain.UserFormItemEntity;
+import com.ltkj.tduck.service.UserFormItemService;
+import lombok.RequiredArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * 涓や釜鍓嶆彁:浣嶇疆鐨勪俊鎭褰曞湪浠诲姟鐨勬ā鍨嬩笂(pos瀛楁);涓�鑸袱涓换鍔$殑pos鍊肩浉宸緢澶�(榛樿鏄�65536);鐜板湪鍋囪鏈変换鍔� A, B, C.
+ * 鍒椾妇鍑犱釜甯歌鐨勫満鏅�:濡傛灉C瑕佺Щ鍒癆鐨勫墠闈�, 閭d箞鍚庣浼氭妸 C.pos 鏀逛负 A.pos/2;鑻ユ灉C瑕佺Щ鍒癆鍜孊涔嬮棿,
+ * 閭d箞鍚庣浼氭妸 C.pos 鏀逛负 (A.pos + B.pos)/2;濡傛灉B瑕佺Щ鍒癈鐨勫悗闈�, 閭d箞鍚庣浼氭妸 B.pos 鏀逛负 C.pos + 65536;
+ * 褰撶劧杩欓噷浼氭湁涓瀬绔儏鍐甸渶瑕佸鐞�(鍋囪pos鏄暣鏁�):濡傛灉 A.pos 鏄� 1, B.pos 鏄� 2, C鎯崇Щ鍒癆鍜孊涔嬮棿, 鍏跺疄鏄病鏈変竴涓暣鏁板彲浠ョ敤鐨�,
+ * 閽堝杩欑鎯呭喌, 鍚庣浼氶噸鏂扮粰鏁翠釜鍒楄〃鐨勪换鍔¢噸鏂板埛涓�閬峱os鍊�.
+ * <p>
+ * 鎷栧姩鎺掑簭宸ュ叿绫�
+ * 绠楁硶鍙傝�� @link https://www.zhihu.com/question/55789722
+ *
+ * @author smalljop
+ */
+@RequiredArgsConstructor
+@Component
+public class SortUtils {
+
+    private final CacheUtils cacheUtils;
+
+    /**
+     * 鎺掑簭榛樿鑷鍥犲瓙
+     */
+    private final Long SORT_DEFAULT_INCR_FACT = 65536L;
+
+    private final UserFormItemService formItemService;
+
+
+    /**
+     * 鑾峰彇鎺掑簭鏁板��
+     *
+     * @param formKey 琛ㄥ崟key
+     * @return 鍒濆鎺掑簭鏁板��
+     */
+    public Long getInitialSortPosition(String formKey) {
+        String redisKey = StrUtil.format(FormRedisKeyConstants.FORM_ITEM_POS_DELTA, formKey);
+        // 妯℃澘鍒涘缓鏃� 鍒濆鎺掑簭鏁板��
+        if (StrUtil.isBlank(cacheUtils.get(redisKey))) {
+            Long sort = formItemService.getLastItemSort(formKey);
+            cacheUtils.save(redisKey, String.valueOf(sort == null ? 1 : sort));
+        }
+        return cacheUtils.incr(redisKey, SORT_DEFAULT_INCR_FACT.intValue());
+    }
+
+
+    /**
+     * * 涓や釜鍓嶆彁:浣嶇疆鐨勪俊鎭褰曞湪浠诲姟鐨勬ā鍨嬩笂(pos瀛楁);涓�鑸袱涓换鍔$殑pos鍊肩浉宸緢澶�(榛樿鏄�65536);鐜板湪鍋囪鏈変换鍔� A, B, C.
+     * * 鍒椾妇鍑犱釜甯歌鐨勫満鏅�:濡傛灉C瑕佺Щ鍒癆鐨勫墠闈�, 閭d箞鍚庣浼氭妸 C.pos 鏀逛负 A.pos/2;鑻ユ灉C瑕佺Щ鍒癆鍜孊涔嬮棿,
+     * * 閭d箞鍚庣浼氭妸 C.pos 鏀逛负 (A.pos + B.pos)/2;濡傛灉B瑕佺Щ鍒癈鐨勫悗闈�, 閭d箞鍚庣浼氭妸 B.pos 鏀逛负 C.pos + 65536;
+     * * 褰撶劧杩欓噷浼氭湁涓瀬绔儏鍐甸渶瑕佸鐞�(鍋囪pos鏄暣鏁�):濡傛灉 A.pos 鏄� 1, B.pos 鏄� 2, C鎯崇Щ鍒癆鍜孊涔嬮棿, 鍏跺疄鏄病鏈変竴涓暣鏁板彲浠ョ敤鐨�,
+     * * 閽堝杩欑鎯呭喌, 鍚庣浼氶噸鏂扮粰鏁翠釜鍒楄〃鐨勪换鍔¢噸鏂板埛涓�閬峱os鍊�.
+     * 鎺掑簭涔嬪悗閲嶆柊璁$畻
+     *
+     * @param beforePosition 涔嬪墠鐨勪綅缃�
+     * @param afterPosition  涔嬪悗鐨勪綅缃�
+     * @param formKey        琛ㄥ崟key
+     * @return 鏈�缁堜綅缃�
+     */
+    public Long calcSortPosition(Long beforePosition, Long afterPosition, String formKey) {
+        String redisKey = StrUtil.format(FormRedisKeyConstants.FORM_ITEM_POS_DELTA, formKey);
+        boolean isCenter = (ObjectUtil.isNotNull(beforePosition) && 0L != beforePosition) && (ObjectUtil.isNotNull(afterPosition) && 0L != afterPosition);
+        if (isCenter) { // 鏀惧埌涓棿
+            return (beforePosition + afterPosition) / 2;
+        }
+        if (ObjectUtil.isNull(beforePosition) || 0L == beforePosition) { // 鏀惧埌鏈�鍓嶉潰
+            return afterPosition / 2;
+        } else { // 鏀惧埌鏈�鍚庨潰
+            return cacheUtils.incr(redisKey, SORT_DEFAULT_INCR_FACT.intValue());
+        }
+    }
+
+
+    /**
+     * 鏋佺鎯呭喌鍒锋柊鏁翠釜鍒楄〃
+     *
+     * @param beforePosition 涔嬪墠鐨勪綅缃�
+     * @param afterPosition  涔嬪悗鐨勪綅缃�
+     * @param formKey        琛ㄥ崟key
+     * @param sort           鎺掑簭鏁板��
+     */
+    public Boolean sortAllList(Long beforePosition, Long afterPosition, String formKey, Long sort) {
+        // 鍗冲皢娌℃湁鏁存暟锛屽埛鏂板叏閮ㄥ垪琛ㄦ帓搴忓��
+        if ((ObjectUtil.isNotNull(beforePosition) && 0L != beforePosition && ObjectUtil.equal(sort, beforePosition + 1))
+                || (ObjectUtil.isNotNull(afterPosition) && 0L != afterPosition && ObjectUtil.equal(sort, 1L))) {
+            List<UserFormItemEntity> itemEntityList = formItemService.list(Wrappers.<UserFormItemEntity>lambdaQuery().eq(UserFormItemEntity::getFormKey, formKey));
+            itemEntityList.sort(Comparator.comparing(UserFormItemEntity::getSort));
+            for (int i = 0; i < itemEntityList.size(); i++) {
+                itemEntityList.get(i).setSort(SORT_DEFAULT_INCR_FACT * (i + 1));
+            }
+            formItemService.updateBatchById(itemEntityList);
+            return true;
+        }
+        return false;
+    }
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/utils/ValidatorUtils.java b/ltkj-system/src/main/java/com/ltkj/tduck/utils/ValidatorUtils.java
new file mode 100644
index 0000000..3764cd0
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/utils/ValidatorUtils.java
@@ -0,0 +1,57 @@
+package com.ltkj.tduck.utils;
+
+
+
+
+import com.ltkj.common.exception.base.BaseException;
+
+import javax.validation.ConstraintViolation;
+import javax.validation.Validation;
+import javax.validation.Validator;
+import java.util.Set;
+
+/**
+ * @description: hibernate 鏍¢獙宸ュ叿绫�
+ * 涓嶉�氳繃娉ㄨВ浣跨敤 閫氳繃宸ュ叿绫昏繑鍥炶嚜瀹氫箟缁撴灉
+ * @author: smalljop
+ * @create: 2018-10-12 10:20
+ **/
+public class ValidatorUtils {
+
+    private static Validator validator;
+
+    static {
+        validator = Validation.buildDefaultValidatorFactory().getValidator();
+    }
+
+    /**
+     * 鏍¢獙瀵硅薄
+     *
+     * @param object 寰呮牎楠屽璞�
+     * @param groups 寰呮牎楠岀殑缁�
+     * @throws BaseException 鏍¢獙涓嶉�氳繃锛孊aseException
+     */
+    public static void validateEntity(Object object, Class<?>... groups)
+            throws BaseException {
+        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object, groups);
+        if (!constraintViolations.isEmpty()) {
+            StringBuilder msg = new StringBuilder();
+            for (ConstraintViolation<Object> constraint : constraintViolations) {
+                msg.append(constraint.getMessage());
+            }
+            throw new BaseException(msg.toString());
+        }
+    }
+
+    public static void validateEntity(Object object)
+            throws BaseException {
+        Set<ConstraintViolation<Object>> constraintViolations = validator.validate(object);
+        if (!constraintViolations.isEmpty()) {
+            StringBuilder msg = new StringBuilder();
+            for (ConstraintViolation<Object> constraint : constraintViolations) {
+                msg.append(constraint.getMessage()).append("<br>");
+            }
+            throw new BaseException(msg.toString());
+        }
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/vo/FormDataTableVO.java b/ltkj-system/src/main/java/com/ltkj/tduck/vo/FormDataTableVO.java
new file mode 100644
index 0000000..d9b6e67
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/vo/FormDataTableVO.java
@@ -0,0 +1,26 @@
+package com.ltkj.tduck.vo;
+
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * 琛ㄥ崟鏁版嵁琛ㄦ牸
+ */
+@Data
+@NoArgsConstructor
+public class FormDataTableVO {
+    /**
+     * 鏁版嵁鍒楄〃
+     */
+    private List<Map> rows;
+
+    private Long total;
+
+    public FormDataTableVO(List<Map> rows, Long total) {
+        this.rows = rows;
+        this.total = total;
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/vo/FormFieldVO.java b/ltkj-system/src/main/java/com/ltkj/tduck/vo/FormFieldVO.java
new file mode 100644
index 0000000..8e283b5
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/vo/FormFieldVO.java
@@ -0,0 +1,64 @@
+package com.ltkj.tduck.vo;
+
+
+import cn.hutool.core.collection.CollUtil;
+import com.ltkj.tduck.domain.UserFormItemEntity;
+import com.ltkj.tduck.utils.FormDataUtils;
+import com.ltkj.tduck.utils.HtmlUtils;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import static com.ltkj.tduck.constant.FormConstants.FIELD_SUFFIX_LABEL;
+
+
+/**
+ * 琛ㄥ崟瀛楁绫�
+ */
+@Data
+@AllArgsConstructor
+@NoArgsConstructor
+public class FormFieldVO {
+
+    /**
+     * 瀛楁Id
+     */
+    protected String value;
+    /**
+     * 瀛楁鍚嶇О
+     */
+    protected String label;
+    /**
+     * 瀛楁绫诲瀷
+     */
+    protected String type;
+
+    /**
+     * 閰嶇疆
+     */
+    protected Object scheme;
+
+    public FormFieldVO(String value, String label) {
+        this.value = value;
+        // 娓呴櫎html閲岄潰鐨勬爣绛�
+        this.label = HtmlUtils.cleanHtmlTag(label);
+    }
+
+    public FormFieldVO(String value, String label, String type) {
+        this.value = value;
+        this.label = HtmlUtils.cleanHtmlTag(label);
+        this.type = type;
+    }
+
+    public FormFieldVO(UserFormItemEntity entity) {
+        this.label = HtmlUtils.cleanHtmlTag(entity.getLabel());
+        this.type = entity.getType().toString();
+        this.value = entity.getFormItemId();
+        //  閫夋嫨鍨嬬粍浠剁壒娈婂鐞�
+        if (CollUtil.contains(FormDataUtils.specialFields, entity.getType())) {
+            this.value = entity.getFormItemId() + FIELD_SUFFIX_LABEL;
+        }
+        //鑾峰彇閰嶇疆椤�
+        this.scheme = entity.getScheme();
+    }
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/vo/OperateFormItemVO.java b/ltkj-system/src/main/java/com/ltkj/tduck/vo/OperateFormItemVO.java
new file mode 100644
index 0000000..30faa06
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/vo/OperateFormItemVO.java
@@ -0,0 +1,37 @@
+package com.ltkj.tduck.vo;
+
+import lombok.AllArgsConstructor;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+
+/**
+ * 鎿嶄綔杩斿洖鏁版嵁
+ */
+@Data
+@NoArgsConstructor
+@AllArgsConstructor
+public class OperateFormItemVO {
+
+    /**
+     * 鎺掑簭鍙�
+     */
+    private Long sort;
+
+    /**
+     * 鏁版嵁Id
+     */
+    private Long itemDataId;
+
+    /**
+     * 鎿嶄綔鏄惁鎴愬姛
+     */
+    private Boolean operateSuccess;
+
+
+    /**
+     * 鍒锋柊鍏ㄩ儴
+     */
+    private Boolean refreshAll;
+
+}
diff --git a/ltkj-system/src/main/java/com/ltkj/tduck/vo/UserFormDetailVO.java b/ltkj-system/src/main/java/com/ltkj/tduck/vo/UserFormDetailVO.java
new file mode 100644
index 0000000..082e3db
--- /dev/null
+++ b/ltkj-system/src/main/java/com/ltkj/tduck/vo/UserFormDetailVO.java
@@ -0,0 +1,62 @@
+package com.ltkj.tduck.vo;
+
+import com.ltkj.tduck.domain.UserFormEntity;
+import com.ltkj.tduck.domain.UserFormItemEntity;
+import com.ltkj.tduck.domain.UserFormLogicEntity;
+import com.ltkj.tduck.domain.UserFormThemeEntity;
+import lombok.AllArgsConstructor;
+import lombok.Data;
+
+import java.util.List;
+
+/**
+ * @author smalljop
+ */
+@Data
+@AllArgsConstructor
+public class UserFormDetailVO {
+    /**
+     * 琛ㄥ崟鍩虹淇℃伅
+     */
+    private UserForm form;
+
+    /**
+     * 琛ㄥ崟椤�
+     */
+    private List<UserFormItemEntity> formItems;
+
+    /**
+     * 涓婚
+     */
+    private UserFormThemeEntity userFormTheme;
+
+    /**
+     * 閫昏緫
+     */
+    private UserFormLogicEntity formLogic;
+
+
+    @Data
+    public static class UserForm {
+        private String formKey;
+        /**
+         * 琛ㄥ崟鍚嶇О
+         */
+        private String name;
+        /**
+         * 琛ㄥ崟鎻忚堪
+         */
+        private String description;
+
+
+        private String type;
+
+        public UserForm(UserFormEntity entity) {
+            this.formKey = entity.getFormKey();
+            this.name = entity.getName();
+            this.description = entity.getDescription();
+            this.type = entity.getType();
+        }
+
+    }
+}

--
Gitblit v1.8.0