Просмотр исходного кода

Merge branch 'dynamic_question'

zoujiajian 3 лет назад
Родитель
Сommit
975609d925
26 измененных файлов с 1161 добавлено и 0 удалено
  1. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormFieldsDataMapper.java
  2. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormFieldsDefaultMapper.java
  3. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormFieldsMapper.java
  4. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormTemplateMapper.java
  5. 13 0
      netflix-dao/src/main/java/com/cyksj/mapper/manage/form/QuestionnairePromotionMapper.java
  6. 33 0
      netflix-dao/src/main/java/com/cyksj/model/dto/FormTemplateDataDto.java
  7. 52 0
      netflix-dao/src/main/java/com/cyksj/model/dto/QuestionnaireFieldsView.java
  8. 48 0
      netflix-dao/src/main/java/com/cyksj/model/dto/QuestionnaireView.java
  9. 45 0
      netflix-dao/src/main/java/com/cyksj/model/entity/FormFields.java
  10. 37 0
      netflix-dao/src/main/java/com/cyksj/model/entity/FormFieldsData.java
  11. 34 0
      netflix-dao/src/main/java/com/cyksj/model/entity/FormFieldsDefault.java
  12. 25 0
      netflix-dao/src/main/java/com/cyksj/model/entity/FormTemplate.java
  13. 36 0
      netflix-dao/src/main/java/com/cyksj/model/entity/QuestionnairePromotion.java
  14. 38 0
      netflix-dao/src/main/java/com/cyksj/model/views/FormFieldsDataView.java
  15. 44 0
      netflix-dao/src/main/java/com/cyksj/model/views/FormSubmitDataView.java
  16. 29 0
      netflix-dao/src/main/java/com/cyksj/model/views/QuestionnaireOptionsView.java
  17. 26 0
      netflix-dao/src/main/java/com/cyksj/model/views/QuestionnairePromotionFieldsListView.java
  18. 45 0
      netflix-dao/src/main/java/com/cyksj/model/views/QuestionnaireView.java
  19. 5 0
      netflix-service/pom.xml
  20. 23 0
      netflix-service/src/main/java/com/cyksj/service/mange/form/FormService.java
  21. 14 0
      netflix-service/src/main/java/com/cyksj/service/mange/form/QuestionnairePromotionService.java
  22. 179 0
      netflix-service/src/main/java/com/cyksj/service/mange/form/impl/FormServiceImpl.java
  23. 37 0
      netflix-service/src/main/java/com/cyksj/service/mange/form/impl/QuestionnairePromotionServiceImpl.java
  24. 56 0
      netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java
  25. 197 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/form/FormController.java
  26. 93 0
      netflix-web/src/main/java/com/cyksj/web/controller/manage/form/QuestionnairePromotionController.java

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormFieldsDataMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.form;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.FormFieldsData;
+
+/*
+ *项目名: netflix
+ *文件名: FormFieldsDataMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/12 10:05
+ */
+public interface FormFieldsDataMapper extends BaseMapper<FormFieldsData> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormFieldsDefaultMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.form;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.FormFieldsDefault;
+
+/*
+ *项目名: netflix
+ *文件名: FormFieldsDefaultMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/12 10:25
+ */
+public interface FormFieldsDefaultMapper extends BaseMapper<FormFieldsDefault> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormFieldsMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.form;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.FormFields;
+
+/*
+ *项目名: netflix
+ *文件名: FormFieldsMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/12 10:03
+ */
+public interface FormFieldsMapper extends BaseMapper<FormFields> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/form/FormTemplateMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.form;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.FormTemplate;
+
+/*
+ *项目名: netflix
+ *文件名: FormTemplateMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/12 10:26
+ */
+public interface FormTemplateMapper extends BaseMapper<FormTemplate> {
+}

+ 13 - 0
netflix-dao/src/main/java/com/cyksj/mapper/manage/form/QuestionnairePromotionMapper.java

@@ -0,0 +1,13 @@
+package com.cyksj.mapper.manage.form;
+
+import com.baomidou.mybatisplus.core.mapper.BaseMapper;
+import com.cyksj.model.entity.QuestionnairePromotion;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnairePromotionMapper
+ *创建者: JavaZou
+ *创建时间:2023/6/12 17:18
+ */
+public interface QuestionnairePromotionMapper extends BaseMapper<QuestionnairePromotion> {
+}

+ 33 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/FormTemplateDataDto.java

@@ -0,0 +1,33 @@
+package com.cyksj.model.dto;
+
+import com.cyksj.model.entity.FormFields;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: FormTemplateDataDto
+ *创建者: JavaZou
+ *创建时间:2023/6/12 15:54
+ */
+@Getter
+@Setter
+public class FormTemplateDataDto {
+	private Long id;
+	/**
+	 * 模板名称
+	 */
+	private String name;
+
+	/**
+	 * 模板描述
+	 */
+	private String descStr;
+
+	/**
+	 * 字段
+	 */
+	private List<FormFields> formFieldsList;
+}

+ 52 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/QuestionnaireFieldsView.java

@@ -0,0 +1,52 @@
+package com.cyksj.model.dto;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnaireFieldsView
+ *创建者: JavaZou
+ *创建时间:2023/6/12 16:23
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_template ft left join form_fields ff on ff.template_id = ft.id" +
+		" left join form_fields_default fd on fd.fields_id = ff.id :promotion_id:",
+		where = "ff.deleted is true and ft.deleted is true")
+public class QuestionnaireFieldsView {
+	@DbField("ff.id")
+	private Long id;
+
+	@DbField("fd.fields_name")
+	private String fieldsName;
+
+	@DbField("ff.data_type")
+	private Integer dataType;
+
+	@DbField("ff.fields_entry_type")
+	private Integer FieldsEntryType;
+
+	@DbField("ff.show_table")
+	private Integer showTable;
+
+	@DbField("ff.sorted")
+	private Integer sorted;
+
+	@DbField("ff.template_id")
+	private Long templateId;
+
+	@DbField("ft.name")
+	private String templateName;
+
+	@DbField("ft.desc_str")
+	private String descStr;
+
+	@DbField("fd.promotion_id")
+	private Long promotionId;
+
+	@DbField("fd.value")
+	private String value;
+}

+ 48 - 0
netflix-dao/src/main/java/com/cyksj/model/dto/QuestionnaireView.java

@@ -0,0 +1,48 @@
+package com.cyksj.model.dto;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnaireView
+ *创建者: JavaZou
+ *创建时间:2023/6/13 11:13
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_fields_default fd left join form_fields ff on ff.id = fd.fields_id",
+		where = "ff.deleted is true")
+public class QuestionnaireView {
+
+	@DbField("fd.fields_id")
+	private Long fieldsId;
+
+	@DbField("fd.promotion_id")
+	private Long promotionId;
+
+	@DbField("fd.fields_name")
+	private String fieldsName;
+
+	@DbField("fd.value")
+	private String value;
+
+	@DbField("ff.data_type")
+	private Integer dataType;
+
+	@DbField("ff.fields_entry_type")
+	private Integer fieldsEntryType;
+
+	@DbField("ff.max_length")
+	private Integer maxLength;
+
+	@DbField("ff.show_table")
+	private Integer showTable;
+
+	@JsonIgnore
+	@DbField("ff.sorted")
+	private Integer sorted;
+}

+ 45 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/FormFields.java

@@ -0,0 +1,45 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: FormFields
+ *创建者: JavaZou
+ *创建时间:2023/6/12 9:49
+ */
+@Getter
+@Setter
+public class FormFields extends BaseEntity{
+	private Long templateId;
+
+	/**
+	 * 字段名称
+	 */
+	private String fieldsName;
+
+	/**
+	 * 字段数据类型1.文字2.数字
+	 */
+	private Integer dataType;
+
+	/**
+	 * 字段录入方式,展示类型,0:单行文本 1:多行文本 2:下拉菜单 3:时间选择框
+	 */
+	private Integer fieldsEntryType;
+
+	private Integer maxLength;
+
+	/**
+	 * 是否列表展示 0:不展示 1:展示
+	 */
+	private Integer showTable;
+
+	/**
+	 * 排序标识
+	 */
+	private Integer sorted;
+
+	private Boolean deleted;
+}

+ 37 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/FormFieldsData.java

@@ -0,0 +1,37 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: FormFieldsData
+ *创建者: JavaZou
+ *创建时间:2023/6/12 9:53
+ */
+@Getter
+@Setter
+public class FormFieldsData extends BaseEntity{
+	/**
+	 * 字段id
+	 */
+	@NotNull(message = "请选择对应问题")
+	private Long fieldsId;
+
+	private Long groupsId;
+
+	private String fieldsName;
+
+	private Long promotionId;
+
+	private Long orderId;
+
+	private Integer sorted;
+
+	@NotNull(message = "请选择对应问题选项")
+	private String content;
+
+	private Boolean deleted;
+}

+ 34 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/FormFieldsDefault.java

@@ -0,0 +1,34 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: FormFieldsDefault
+ *创建者: JavaZou
+ *创建时间:2023/6/12 9:54
+ */
+@Getter
+@Setter
+public class FormFieldsDefault extends BaseEntity{
+	/**
+	 * 活动id
+	 */
+	private Long promotionId;
+
+	/**
+	 * 字段id
+	 */
+	private Long fieldsId;
+
+	/**
+	 * 字段名称
+	 */
+	private String fieldsName;
+
+	/**
+	 * 默认值 问题选项数组
+	 */
+	private String value;
+}

+ 25 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/FormTemplate.java

@@ -0,0 +1,25 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: FormTemplate
+ *创建者: JavaZou
+ *创建时间:2023/6/12 9:56
+ */
+@Getter
+@Setter
+public class FormTemplate extends BaseEntity{
+	/**
+	 * 模板名称
+	 */
+	private String name;
+	/**
+	 * 描述
+	 */
+	private String descStr;
+
+	private Boolean deleted;
+}

+ 36 - 0
netflix-dao/src/main/java/com/cyksj/model/entity/QuestionnairePromotion.java

@@ -0,0 +1,36 @@
+package com.cyksj.model.entity;
+
+import lombok.Getter;
+import lombok.Setter;
+import org.hibernate.validator.constraints.Length;
+
+import javax.validation.constraints.NotEmpty;
+import javax.validation.constraints.NotNull;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnairePromotion
+ *创建者: JavaZou
+ *创建时间:2023/6/12 17:17
+ */
+@Getter
+@Setter
+public class QuestionnairePromotion extends BaseEntity{
+	@NotNull(message = "模板id为空")
+	private Long templateId;
+
+	@NotEmpty(message = "问卷活动名称为空")
+	@Length(max = 100)
+	private String name;
+
+	private String remark;
+
+	private Boolean deleted;
+
+	private Boolean status;
+
+	/**
+	 * 是否上架过
+	 */
+	private Boolean isUp;
+}

+ 38 - 0
netflix-dao/src/main/java/com/cyksj/model/views/FormFieldsDataView.java

@@ -0,0 +1,38 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: FormFieldsDataView
+ *创建者: JavaZou
+ *创建时间:2023/6/12 14:13
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_fields_data fa",
+		where = "fa.deleted is true :time_sql:")
+public class FormFieldsDataView {
+	@DbField("fa.id")
+	private Integer id;
+
+	@DbField("fa.promotion_id")
+	private Long promotionId;
+
+	@DbField("fa.fields_name")
+	private String fieldsName;
+
+	@DbField("fa.fields_id")
+	private Long fieldsId;
+
+	@DbField("fa.content")
+	private String content;
+
+	@DbField("fa.created_time")
+	private Date createdTime;
+}

+ 44 - 0
netflix-dao/src/main/java/com/cyksj/model/views/FormSubmitDataView.java

@@ -0,0 +1,44 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+import java.util.Date;
+
+/*
+ *项目名: netflix
+ *文件名: FormSubmitDataView
+ *创建者: JavaZou
+ *创建时间:2023/6/15 11:55
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_fields_data fd left join form_fields ff on ff.id = fd.fields_id",
+		where = "fd.deleted is true :time_sql:")
+public class FormSubmitDataView {
+	@DbField("fd.id")
+	private Long id;
+
+	@DbField("fd.groups_id")
+	private Long groupsId;
+
+	@DbField("fd.fields_id")
+	private Long fieldsId;
+
+	@DbField("fd.fields_name")
+	private String fieldsName;
+
+	@DbField("fd.promotion_id")
+	private Long promotionId;
+
+	@DbField("fd.content")
+	private String content;
+
+	@DbField("ff.sorted")
+	private Integer sorted;
+
+	@DbField("fd.created_time")
+	private Date createdTime;
+}

+ 29 - 0
netflix-dao/src/main/java/com/cyksj/model/views/QuestionnaireOptionsView.java

@@ -0,0 +1,29 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnaireOptionsView
+ *创建者: JavaZou
+ *创建时间:2023/6/13 13:38
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_fields_default fd")
+public class QuestionnaireOptionsView {
+	@DbField("fd.fields_id")
+	private Long fieldsId;
+
+	@DbField("fd.promotion_id")
+	private Long promotionId;
+
+	@DbField("fd.fields_name")
+	private String fieldsName;
+
+	@DbField("fd.value")
+	private String value;
+}

+ 26 - 0
netflix-dao/src/main/java/com/cyksj/model/views/QuestionnairePromotionFieldsListView.java

@@ -0,0 +1,26 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnairePromotionFieldsListView
+ *创建者: JavaZou
+ *创建时间:2023/6/15 11:15
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_fields_default fd")
+public class QuestionnairePromotionFieldsListView {
+	@DbField("fd.promotion_id")
+	private Long promotionId;
+
+	@DbField("fd.fields_id")
+	private Long fieldsId;
+
+	@DbField("fd.value")
+	private String value;
+}

+ 45 - 0
netflix-dao/src/main/java/com/cyksj/model/views/QuestionnaireView.java

@@ -0,0 +1,45 @@
+package com.cyksj.model.views;
+
+import com.ejlchina.searcher.bean.DbField;
+import com.ejlchina.searcher.bean.SearchBean;
+import com.fasterxml.jackson.annotation.JsonIgnore;
+import lombok.Getter;
+import lombok.Setter;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnaireView
+ *创建者: JavaZou
+ *创建时间:2023/6/13 11:13
+ */
+@Getter
+@Setter
+@SearchBean(tables = "form_template fd left join form_fields ff on ff.template_id = fd.id",
+		where = "fd.deleted is true and ff.deleted is true")
+public class QuestionnaireView {
+
+	@DbField("fd.promotion_id")
+	private Long promotionId;
+
+	@DbField("ff.id")
+	private Long fieldsId;
+
+	@DbField("ff.fields_name")
+	private String fieldsName;
+
+	@DbField("ff.data_type")
+	private Integer dataType;
+
+	@DbField("ff.fields_entry_type")
+	private Integer FieldsEntryType;
+
+	@DbField("ff.max_length")
+	private Integer maxLength;
+
+	@DbField("ff.show_table")
+	private Integer showTable;
+
+	@DbField("ff.sorted")
+	@JsonIgnore
+	private Integer sorted;
+}

+ 5 - 0
netflix-service/pom.xml

@@ -35,6 +35,11 @@
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-mail</artifactId>
         </dependency>
+
+        <dependency>
+            <groupId>org.springframework.boot</groupId>
+            <artifactId>spring-boot-starter-web</artifactId>
+        </dependency>
     </dependencies>
 
 </project>

+ 23 - 0
netflix-service/src/main/java/com/cyksj/service/mange/form/FormService.java

@@ -0,0 +1,23 @@
+package com.cyksj.service.mange.form;
+
+import com.cyksj.model.dto.FormTemplateDataDto;
+import com.cyksj.model.entity.FormFieldsDefault;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.Date;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: FormService
+ *创建者: JavaZou
+ *创建时间:2023/6/12 15:57
+ */
+public interface FormService {
+
+	void saveOrUpdateTemplateAndRelationFields(FormTemplateDataDto dataDto);
+
+	void exportQuestionInfo(Long promotionId, Date start, Date end, HttpServletResponse response) throws Exception;
+
+	void saveOrUpdateTemplateFieldsValue(List<FormFieldsDefault> values);
+}

+ 14 - 0
netflix-service/src/main/java/com/cyksj/service/mange/form/QuestionnairePromotionService.java

@@ -0,0 +1,14 @@
+package com.cyksj.service.mange.form;
+
+import com.baomidou.mybatisplus.extension.service.IService;
+import com.cyksj.model.entity.QuestionnairePromotion;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnairePromotionService
+ *创建者: JavaZou
+ *创建时间:2023/6/14 11:42
+ */
+public interface QuestionnairePromotionService extends IService<QuestionnairePromotion> {
+	Long saveOrUpdatePromotion(QuestionnairePromotion promotion);
+}

+ 179 - 0
netflix-service/src/main/java/com/cyksj/service/mange/form/impl/FormServiceImpl.java

@@ -0,0 +1,179 @@
+package com.cyksj.service.mange.form.impl;
+
+import cn.hutool.core.collection.CollUtil;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.alibaba.excel.EasyExcel;
+import com.alibaba.excel.support.ExcelTypeEnum;
+import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.mapper.manage.form.*;
+import com.cyksj.model.dto.FormTemplateDataDto;
+import com.cyksj.model.entity.FormFields;
+import com.cyksj.model.entity.FormFieldsDefault;
+import com.cyksj.model.entity.FormTemplate;
+import com.cyksj.model.entity.QuestionnairePromotion;
+import com.cyksj.model.views.FormSubmitDataView;
+import com.cyksj.service.mange.form.FormService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.util.MapBuilder;
+import com.ejlchina.searcher.util.MapUtils;
+import com.google.common.collect.Lists;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.servlet.http.HttpServletResponse;
+import java.util.ArrayList;
+import java.util.Date;
+import java.util.List;
+import java.util.Map;
+import java.util.stream.Collectors;
+
+/*
+ *项目名: netflix
+ *文件名: FormServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/6/12 15:58
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class FormServiceImpl implements FormService {
+	private final FormFieldsMapper formFieldsMapper;
+
+	private final FormFieldsDataMapper formFieldsDataMapper;
+
+	private final FormTemplateMapper formTemplateMapper;
+
+	private final FormFieldsDefaultMapper formFieldsDefaultMapper;
+
+	private final QuestionnairePromotionMapper questionnairePromotionMapper;
+
+	private final BeanSearcher beanSearcher;
+
+	@Override
+	@Transactional(rollbackFor = Throwable.class)
+	public void saveOrUpdateTemplateAndRelationFields(FormTemplateDataDto dataDto) {
+		Long templateId = saveOrUpdateTemplate(dataDto.getId(), dataDto.getName(), dataDto.getDescStr());
+
+		saveOrUpdateTemplateFields(templateId, dataDto.getFormFieldsList());
+	}
+
+	@Override
+	public void exportQuestionInfo(Long promotionId, Date start, Date end, HttpServletResponse response) throws Exception {
+		QuestionnairePromotion promotion = questionnairePromotionMapper.selectById(promotionId);
+		if (promotion == null) throw BusinessRuntimeException.getInstance("问卷活动不存在");
+		String fileName = promotion.getName();
+		response.setContentType("application/x-download");
+		response.setContentType("application/vnd.ms-excel");
+		response.setCharacterEncoding("utf-8");
+		response.setHeader("Content-disposition",
+				"attachment;filename=" + new String(fileName.getBytes("utf-8"), "ISO-8859-1") + ExcelTypeEnum.XLS.getValue());
+		List<FormFields> formFields = formFieldsMapper.selectList(new LambdaQueryWrapper<FormFields>().eq(FormFields::getTemplateId, promotion.getTemplateId()).orderByAsc(FormFields::getSorted));
+		List<List<String>> data = data(promotionId, formFields, start, end);
+		EasyExcel.write(response.getOutputStream())
+				// 这里放入动态头
+				.head(head(formFields)).sheet("问卷信息")
+				// 当然这里数据也可以用 List<List<String>> 去传入
+				.doWrite(data);
+	}
+
+	@Override
+	public void saveOrUpdateTemplateFieldsValue(List<FormFieldsDefault> values) {
+		values.forEach(formFieldsDefault ->{
+			FormFieldsDefault dbFieldDefault = formFieldsDefaultMapper.selectOne(Wrappers.lambdaQuery(FormFieldsDefault.class)
+					.eq(FormFieldsDefault::getFieldsId, formFieldsDefault.getFieldsId()).last("limit 1"));
+			if (dbFieldDefault == null){
+				formFieldsDefaultMapper.insert(formFieldsDefault);
+				return;
+			}
+			formFieldsDefault.setId(dbFieldDefault.getId());
+			formFieldsDefaultMapper.updateById(formFieldsDefault);
+		});
+	}
+
+	public Long saveOrUpdateTemplate(Long templateId, String name, String descStr) {
+		FormTemplate formTemplate;
+		if (templateId == null) {
+			formTemplate = new FormTemplate();
+			formTemplate.setName(name);
+			formTemplate.setDescStr(descStr);
+			formTemplateMapper.insert(formTemplate);
+			return formTemplate.getId();
+		}
+		formTemplate = formTemplateMapper.selectById(templateId);
+		formTemplate.setName(name);
+		formTemplate.setDescStr(descStr);
+		formTemplateMapper.updateById(formTemplate);
+		return formTemplate.getId();
+	}
+
+	private void saveOrUpdateTemplateFields(Long templateId, List<FormFields> formFieldsList) {
+		List<Long> filedIds = new ArrayList<>();
+		formFieldsList.forEach(field -> {
+			Long fieldId = field.getId();
+			if (fieldId == null) {
+				field.setTemplateId(templateId);
+				formFieldsMapper.insert(field);
+			} else {
+				formFieldsMapper.updateById(field);
+			}
+			filedIds.add(fieldId);
+		});
+
+		formFieldsMapper.delete(Wrappers.lambdaQuery(FormFields.class)
+				.eq(FormFields::getTemplateId, templateId)
+				.notIn(FormFields::getId, filedIds));
+	}
+
+
+	private List<List<String>> head(List<FormFields> formFields) {
+		List<List<String>> headTitles = new ArrayList<>();
+		formFields.forEach((field) -> {
+			headTitles.add(Lists.newArrayList(field.getFieldsName()));
+		});
+		headTitles.add(Lists.newArrayList("提交时间"));
+		return headTitles;
+	}
+
+	private List<List<String>> data(Long promotionId, List<FormFields> formFields, Date start, Date end) {
+//		List<FormFieldsData> fieldsDataList = formFieldsDataMapper.selectList(new LambdaQueryWrapper<FormFieldsData>().eq(FormFieldsData::getPromotionId, promotionId).eq(FormFieldsData::getDeleted, true).orderByAsc(FormFieldsData::getSorted));
+		String timeSql = StrUtil.EMPTY;
+		if (start != null) {
+			timeSql += String.format(" and fd.created_time >= '%s'", start);
+		}
+		if (end != null) {
+			timeSql += String.format(" and fd.created_time < '%s'", end);
+		}
+		MapBuilder builder = MapUtils.builder()
+				.field(FormSubmitDataView::getPromotionId, promotionId)
+				.orderBy(FormSubmitDataView::getSorted).asc();
+		if (StrUtil.isNotBlank(timeSql)) {
+			builder.put("time_sql", timeSql);
+		}
+		List<FormSubmitDataView> formSubmitDataViews = beanSearcher.searchAll(FormSubmitDataView.class, builder.build());
+		if (formSubmitDataViews.isEmpty()) {
+			throw BusinessRuntimeException.getInstance("暂无数据");
+		}
+		List<List<String>> contentList = Lists.newArrayList();
+		Map<Long, List<FormSubmitDataView>> collect = formSubmitDataViews.stream().collect(Collectors.groupingBy(FormSubmitDataView::getGroupsId));
+		collect.forEach((groupsId, answers) -> {
+			Map<Long, List<FormSubmitDataView>> fieldsValueMap = answers.stream().collect(Collectors.groupingBy(FormSubmitDataView::getFieldsId));
+			ArrayList<String> dataList = new ArrayList<>();
+			formFields.forEach(fields -> {
+				List<FormSubmitDataView> values = fieldsValueMap.get(fields.getId());
+				if (CollUtil.isEmpty(values)) {
+					dataList.add(StrUtil.EMPTY);
+					return;
+				}
+				dataList.add(values.get(0).getContent());
+			});
+			dataList.add(DateUtil.format(answers.get(answers.size() - 1).getCreatedTime(), "yyyy-MM-dd HH:mm:ss"));
+			contentList.add(dataList);
+		});
+		return contentList;
+	}
+}

+ 37 - 0
netflix-service/src/main/java/com/cyksj/service/mange/form/impl/QuestionnairePromotionServiceImpl.java

@@ -0,0 +1,37 @@
+package com.cyksj.service.mange.form.impl;
+
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.cyksj.mapper.manage.form.QuestionnairePromotionMapper;
+import com.cyksj.model.entity.QuestionnairePromotion;
+import com.cyksj.service.mange.form.QuestionnairePromotionService;
+import lombok.RequiredArgsConstructor;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.stereotype.Service;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnairePromotionServiceImpl
+ *创建者: JavaZou
+ *创建时间:2023/6/14 11:42
+ */
+@Service
+@RequiredArgsConstructor
+@Slf4j
+public class QuestionnairePromotionServiceImpl extends ServiceImpl<QuestionnairePromotionMapper, QuestionnairePromotion> implements QuestionnairePromotionService {
+	private final QuestionnairePromotionMapper promotionMapper;
+
+	@Override
+	public Long saveOrUpdatePromotion(QuestionnairePromotion promotion) {
+		if (promotion.getId() == null) {
+			promotionMapper.insert(promotion);
+			return promotion.getId();
+		}
+		QuestionnairePromotion db = promotionMapper.selectById(promotion.getId());
+		if (db.getIsUp()) {
+			promotion.setTemplateId(null);
+			promotion.setIsUp(true);
+		}
+		promotionMapper.updateById(promotion);
+		return promotion.getId();
+	}
+}

+ 56 - 0
netflix-web/src/main/java/com/cyksj/web/controller/group/GroupRelationController.java

@@ -1,5 +1,6 @@
 package com.cyksj.web.controller.group;
 
+import cn.hutool.core.collection.CollUtil;
 import cn.hutool.core.date.DateTime;
 import cn.hutool.core.date.DateUtil;
 import cn.hutool.core.thread.ThreadUtil;
@@ -7,7 +8,9 @@ import cn.hutool.core.util.StrUtil;
 import cn.hutool.extra.servlet.ServletUtil;
 import cn.hutool.json.JSONObject;
 import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.annotation.NoSubmit;
 import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.common.snowflake.Sequence;
 import com.cyksj.common.task.GlobalThreadPoolTaskExecutor;
 import com.cyksj.common.util.GoogleGenerator;
 import com.cyksj.common.util.Jsons;
@@ -15,11 +18,15 @@ import com.cyksj.common.util.StringUtil;
 import com.cyksj.dto.Result;
 import com.cyksj.enums.GatewayResponse;
 import com.cyksj.mapper.*;
+import com.cyksj.mapper.manage.form.FormFieldsDataMapper;
+import com.cyksj.mapper.manage.form.QuestionnairePromotionMapper;
 import com.cyksj.model.dto.DoubleVerifyDto;
+import com.cyksj.model.dto.QuestionnaireView;
 import com.cyksj.model.entity.*;
 import com.cyksj.model.manage.views.GroupsRelationView;
 import com.cyksj.model.request.OrderPayRequest;
 import com.cyksj.model.views.DoubleVerifyCodeView;
+import com.cyksj.model.views.QuestionnairePromotionFieldsListView;
 import com.cyksj.model.views.RenewalView;
 import com.cyksj.model.views.UserTicketView;
 import com.cyksj.redis.RedisService;
@@ -33,6 +40,7 @@ import com.ejlchina.searcher.param.Operator;
 import com.ejlchina.searcher.util.MapUtils;
 import lombok.RequiredArgsConstructor;
 import lombok.extern.slf4j.Slf4j;
+import org.springframework.transaction.annotation.Transactional;
 import org.springframework.validation.annotation.Validated;
 import org.springframework.web.bind.annotation.*;
 
@@ -78,8 +86,16 @@ public class GroupRelationController {
 
     private final CouponCommonService couponCommonService;
 
+    private final FormFieldsDataMapper formFieldsDataMapper;
+
+    private final QuestionnairePromotionMapper questionnairePromotionMapper;
+
+    private final QuestionnairePromotionMapper promotionMapper;
+
     private final GlobalThreadPoolTaskExecutor THREAD_POOL;
 
+    private final static Sequence SEQUENCE = new Sequence(0);
+
     @RequestMapping("/get/renewal")
     public Result<List<RenewalView>> get(Boolean isLoginPopularize) {
         long userId = StpUserUtil.getLoginIdAsLong();
@@ -379,4 +395,44 @@ public class GroupRelationController {
         }
         return GatewayResponse.SUCCESS.newBuilder().toResult();
     }
+
+    /**
+     * 获取对应的动态问卷
+     */
+    @GetMapping("/get/questionnaire")
+    public Result<List<QuestionnaireView>> getQuestionnaireView(Long promotionId) {
+        QuestionnairePromotion promotion = questionnairePromotionMapper.selectById(promotionId);
+        if (promotion == null || !promotion.getDeleted()) throw BusinessRuntimeException.getInstance("问卷不存在");
+        Long templateId = promotion.getTemplateId();
+        List<QuestionnaireView> questionnaireViews = beanSearcher.searchAll(QuestionnaireView.class, MapUtils.builder()
+                .field(QuestionnaireView::getPromotionId, promotionId)
+                .orderBy(QuestionnaireView::getSorted).asc()
+                .orderBy(QuestionnaireView::getFieldsId).asc()
+                .build());
+        return GatewayResponse.SUCCESS.newBuilder().toResult(questionnaireViews);
+    }
+
+    /**
+     * 记录问卷
+     */
+    @PostMapping("/record/questionnaire/{promotionId}")
+    @Transactional(rollbackFor = Exception.class)
+    @NoSubmit
+    public Result<String> recordQuestionnaire(@PathVariable Long promotionId, @RequestBody List<FormFieldsData> answers) {
+        Long groupsId = SEQUENCE.nextId();
+        List<QuestionnairePromotionFieldsListView> promotionFieldsListViews = beanSearcher.searchAll(QuestionnairePromotionFieldsListView.class, MapUtils.builder().field(QuestionnairePromotionFieldsListView::getPromotionId, promotionId).build());
+        if (CollUtil.isEmpty(promotionFieldsListViews)) throw BusinessRuntimeException.getInstance("问卷已结束");
+        if (promotionFieldsListViews.size() != answers.size()) throw BusinessRuntimeException.getInstance("请完成所有问题");
+        answers.forEach(answer -> {
+            Long fieldsId = answer.getFieldsId();
+            String content = answer.getContent();
+            if (fieldsId == null || StrUtil.isBlank(content)) {
+                throw BusinessRuntimeException.getInstance("必填项为空");
+            }
+            answer.setPromotionId(promotionId);
+            answer.setGroupsId(groupsId);
+            formFieldsDataMapper.insert(answer);
+        });
+        return GatewayResponse.SUCCESS.newBuilder().toResult();
+    }
 }

+ 197 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/form/FormController.java

@@ -0,0 +1,197 @@
+package com.cyksj.web.controller.manage.form;
+
+import cn.hutool.core.date.DateTime;
+import cn.hutool.core.date.DateUtil;
+import cn.hutool.core.util.StrUtil;
+import com.baomidou.mybatisplus.core.toolkit.Wrappers;
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.mapper.manage.form.FormFieldsDataMapper;
+import com.cyksj.mapper.manage.form.FormFieldsMapper;
+import com.cyksj.mapper.manage.form.FormTemplateMapper;
+import com.cyksj.model.dto.FormTemplateDataDto;
+import com.cyksj.model.entity.FormFields;
+import com.cyksj.model.entity.FormFieldsDefault;
+import com.cyksj.model.entity.FormTemplate;
+import com.cyksj.model.entity.QuestionnairePromotion;
+import com.cyksj.model.views.FormFieldsDataView;
+import com.cyksj.service.mange.form.FormService;
+import com.cyksj.service.mange.form.QuestionnairePromotionService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapBuilder;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.util.List;
+
+/*
+ *项目名: netflix
+ *文件名: FormController
+ *创建者: JavaZou
+ *创建时间:2023/6/12 9:58
+ */
+@RestController
+@RequestMapping("/manage/form")
+@RequiredArgsConstructor
+public class FormController {
+
+	private final FormFieldsMapper formFieldsMapper;
+
+	private final FormFieldsDataMapper formFieldsDataMapper;
+
+	private final FormTemplateMapper formTemplateMapper;
+
+	private final FormService formService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final QuestionnairePromotionService promotionService;
+
+	private final HttpServletRequest request;
+
+	/**
+	 * 新增模板 以及对应模板字段
+	 */
+	@PostMapping("/template/post")
+	public Result<String> insertTemplateAndRelationFields(@RequestBody FormTemplateDataDto dataDto) {
+		formService.saveOrUpdateTemplateAndRelationFields(dataDto);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 编辑模板以及对应模板字段
+	 */
+	@PutMapping("/template/put")
+	public Result<String> updateTemplateAndRelationFields(@RequestBody FormTemplateDataDto dataDto) {
+		formService.saveOrUpdateTemplateAndRelationFields(dataDto);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 选择模板 生成对应问题
+	 */
+	@PostMapping("/template/fields/value")
+	public Result<String> postTemplateFieldsValue(@RequestBody List<FormFieldsDefault> values) {
+		formService.saveOrUpdateTemplateFieldsValue(values);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 选择模板 修改对应问题
+	 */
+	@PutMapping("/template/fields/value")
+	public Result<String> updateTemplateFieldsValue(@RequestBody List<FormFieldsDefault> values) {
+		formService.saveOrUpdateTemplateFieldsValue(values);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 删除模板
+	 */
+	@PutMapping("/template/del/{id}")
+	public Result<String> delTid(@PathVariable Long id) {
+		formTemplateMapper.update(null, Wrappers.lambdaUpdate(FormTemplate.class)
+				.set(FormTemplate::getDeleted, false)
+				.eq(FormTemplate::getId, id));
+
+		formFieldsMapper.update(null, Wrappers.lambdaUpdate(FormFields.class)
+				.set(FormFields::getDeleted, false)
+				.eq(FormFields::getTemplateId, id));
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	/**
+	 * 问卷表单模板列表
+	 */
+	@GetMapping("/template/get")
+	public Result<SearchResult<FormTemplate>> getTemplate() {
+		SearchResult<FormTemplate> search = beanSearcher.search(FormTemplate.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(FormTemplate::getDeleted, true)
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 问卷表单模板 对应模板字段列表
+	 */
+	@GetMapping("/template/fields/get")
+	public Result<SearchResult<FormFields>> getTemplateFields() {
+		SearchResult<FormFields> search = beanSearcher.search(FormFields.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(FormFields::getDeleted, true)
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 用户问卷回答列表
+	 */
+	@GetMapping("/get/question/resp/data")
+	public Result<SearchResult<FormFieldsDataView>> getData(Long promotionId, Long fieldsId, Long startTime, Long endTime) {
+		DateTime startDate = null;
+		DateTime endDate = null;
+		if (startTime != null) {
+			startDate = DateUtil.date(startTime);
+		}
+		if (endTime != null) {
+			endDate = DateUtil.date(endTime);
+		}
+		if (startDate == null) {
+			startDate = DateUtil.beginOfDay(DateTime.now());
+		}
+		if (endDate == null) {
+			endDate = DateUtil.offsetDay(startDate, 1);
+		}
+		if (promotionId != null) {
+			QuestionnairePromotion byId = promotionService.getById(promotionId);
+			if (byId == null) throw BusinessRuntimeException.getInstance("问卷不存在");
+			if (byId.getName().contains("商务")) {
+				FormFields fields = formFieldsMapper.selectOne(Wrappers.lambdaQuery(FormFields.class).eq(FormFields::getTemplateId, byId.getTemplateId())
+						.like(FormFields::getFieldsName, "渠道").last("limit 1"));
+				if (fields != null) {
+					fieldsId = fields.getId();
+				}
+			}
+		}
+		String timeSql = StrUtil.EMPTY;
+		if (startDate != null) {
+			timeSql += String.format(" and fa.created_time >= '%s'", startDate);
+		}
+		if (endDate != null) {
+			timeSql += String.format(" and fa.created_time < '%s'", endDate);
+		}
+		MapBuilder builder = MapUtils.flatBuilder(request.getParameterMap())
+				.field(FormFieldsDataView::getFieldsId, fieldsId);
+		if (StrUtil.isNotBlank(timeSql)) {
+			builder.put("time_sql", timeSql);
+		}
+		SearchResult<FormFieldsDataView> search = beanSearcher.search(FormFieldsDataView.class, builder.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * @param promotionId
+	 */
+	@GetMapping("/export/question/resp/data")
+	public void exportQuestionInfo(@RequestParam(required = false, defaultValue = "1") Long promotionId, Long startTime, Long endTime, String charset, HttpServletResponse response) throws Exception {
+		DateTime startDate = null;
+		DateTime endDate = null;
+		if (startTime != null) {
+			startDate = DateUtil.date(startTime);
+		}
+		if (endTime != null) {
+			endDate = DateUtil.date(endTime);
+		}
+		if (startDate == null) {
+			startDate = DateUtil.beginOfDay(DateTime.now());
+		}
+		if (endDate == null) {
+			endDate = DateUtil.offsetDay(startDate, 1);
+		}
+		formService.exportQuestionInfo(promotionId, startDate, endDate, response);
+	}
+}

+ 93 - 0
netflix-web/src/main/java/com/cyksj/web/controller/manage/form/QuestionnairePromotionController.java

@@ -0,0 +1,93 @@
+package com.cyksj.web.controller.manage.form;
+
+import com.cyksj.common.exception.BusinessRuntimeException;
+import com.cyksj.dto.Result;
+import com.cyksj.enums.GatewayResponse;
+import com.cyksj.model.dto.QuestionnaireFieldsView;
+import com.cyksj.model.entity.QuestionnairePromotion;
+import com.cyksj.service.mange.form.QuestionnairePromotionService;
+import com.ejlchina.searcher.BeanSearcher;
+import com.ejlchina.searcher.SearchResult;
+import com.ejlchina.searcher.util.MapUtils;
+import lombok.RequiredArgsConstructor;
+import org.springframework.validation.annotation.Validated;
+import org.springframework.web.bind.annotation.*;
+
+import javax.servlet.http.HttpServletRequest;
+
+/*
+ *项目名: netflix
+ *文件名: QuestionnairePromotionController
+ *创建者: JavaZou
+ *创建时间:2023/6/14 11:36
+ */
+@RestController
+@RequestMapping("/manage/questionnaire")
+@RequiredArgsConstructor
+public class QuestionnairePromotionController {
+	private final QuestionnairePromotionService promotionService;
+
+	private final BeanSearcher beanSearcher;
+
+	private final HttpServletRequest request;
+
+	@PostMapping("/post")
+	public Result<Long> saveQuestionnaire(@RequestBody @Validated QuestionnairePromotion promotion) {
+		Long promotionId = promotionService.saveOrUpdatePromotion(promotion);
+		return GatewayResponse.SUCCESS.newBuilder().toResult(promotionId);
+	}
+
+	@PutMapping("/put")
+	public Result<String> updateQuestionnaire(@RequestBody @Validated QuestionnairePromotion promotion) {
+		promotionService.saveOrUpdatePromotion(promotion);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	@DeleteMapping("/delete/{id}")
+	public Result<String> delById(@PathVariable Long id) {
+		QuestionnairePromotion byId = promotionService.getById(id);
+		if (byId == null || !byId.getDeleted()) throw BusinessRuntimeException.getInstance("该记录已被删除");
+		byId.setDeleted(false);
+		promotionService.updateById(byId);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+
+	@GetMapping("/get")
+	public Result<SearchResult<QuestionnairePromotion>> getPromotions() {
+		SearchResult<QuestionnairePromotion> search = beanSearcher.search(QuestionnairePromotion.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(QuestionnairePromotion::getDeleted, true).build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 问卷详情 问卷字段以及答案列表
+	 */
+	@GetMapping("/template/get/detail/{promotionId}")
+	public Result<SearchResult<QuestionnaireFieldsView>> getFieldsView(@PathVariable Long promotionId) {
+		QuestionnairePromotion byId = promotionService.getById(promotionId);
+		if (byId==null) throw BusinessRuntimeException.getInstance("问卷不存在");
+		SearchResult<QuestionnaireFieldsView> search = beanSearcher.search(QuestionnaireFieldsView.class, MapUtils.flatBuilder(request.getParameterMap())
+				.field(QuestionnaireFieldsView::getTemplateId, byId.getTemplateId())
+				.put("promotion_id", String.format(" and fd.promotion_id = %s", promotionId))
+				.orderBy(QuestionnaireFieldsView::getSorted).asc()
+				.build());
+		return GatewayResponse.SUCCESS.newBuilder().toResult(search);
+	}
+
+	/**
+	 * 上下架问卷
+	 */
+	@PutMapping("/update/status/{id}")
+	public Result<String> updateStatusById(@PathVariable Long id) {
+		QuestionnairePromotion promotion = promotionService.getById(id);
+		Boolean status = promotion.getStatus();
+		Boolean isUp = promotion.getIsUp();
+		//上架
+		if (!status && !isUp) {
+			promotion.setIsUp(true);
+		}
+		promotion.setStatus(!status);
+		promotionService.updateById(promotion);
+		return GatewayResponse.SUCCESS.newBuilder().toResult();
+	}
+}