增加活动表单设计的功能

This commit is contained in:
Wang 2026-01-13 10:22:34 +08:00
parent 0047275149
commit e9616a69c5
70 changed files with 3243 additions and 4 deletions

File diff suppressed because one or more lines are too long

View File

@ -43,6 +43,20 @@ public class PageConverterUtils {
return result;
}
public static <T, R> PageListBean<R> convertPageListBean(
IPage<T> sourcePage,
List<R> records) {
PageListBean<R> result = new PageListBean<>();
if (null == sourcePage || sourcePage.getRecords() == null || sourcePage.getRecords().isEmpty()) {
return result;
}
result.setList(records);
result.setPageSize(sourcePage.getSize());
result.setTotalPage(sourcePage.getPages());
result.setTotal(sourcePage.getTotal());
return result;
}
/**
* 分页数据转换方法
* 将MyBatis-Plus的IPage分页结果转换为目标分页Bean

View File

@ -757,7 +757,10 @@
<encoding>UTF-8</encoding>
<debug>true</debug>
<debuglevel>lines,vars,source</debuglevel>
<compilerArgument>-parameters</compilerArgument>
<compilerArgument>
<arg>-parameters</arg>
<arg>-Xlint:-options</arg>
</compilerArgument>
</configuration>
</plugin>

View File

@ -0,0 +1,46 @@
package com.seer.teach.mp.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
/**
* <p>
* 活动表单执行实例DTO
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Schema(name = "ActivityFormExecutionDTO", description = "活动表单执行实例DTO")
@Data
public class ActivityFormExecutionDTO {
private Integer id;
@Schema(description = "执行编号")
private String executionNo;
@Schema(description = "活动ID")
private Integer activityId;
@Schema(description = "代理商ID")
private Integer agentId;
@Schema(description = "使用的表单模板ID")
private Integer templateId;
@Schema(description = "提交人ID家长ID")
private Integer submitterId;
@Schema(description = "提交人姓名")
private String submitterName;
@Schema(description = "提交时间")
private LocalDateTime submitTime;
@Schema(description = "状态draft-草稿submitted-已提交approved-已批准rejected-已拒绝")
private String status;
}

View File

@ -0,0 +1,50 @@
package com.seer.teach.mp.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* <p>
* 活动表单字段DTO
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Schema(name = "ActivityFormFieldDTO", description = "活动表单字段DTO")
@Data
public class ActivityFormFieldDTO {
private Integer id;
@Schema(description = "所属模板ID")
private Integer templateId;
@Schema(description = "字段名称")
private String fieldName;
@Schema(description = "字段代码(英文标识)")
private String fieldCode;
@Schema(description = "字段类型text, textarea, select, radio, checkbox, date, number等")
private String fieldType;
@Schema(description = "字段选项JSON格式适用于select, radio, checkbox等")
private String fieldOptions;
@Schema(description = "占位符提示")
private String placeholder;
@Schema(description = "是否必填0-否1-是")
private Integer isRequired;
@Schema(description = "排序")
private Integer sortOrder;
@Schema(description = "验证规则JSON格式")
private String validationRules;
@Schema(description = "字段描述")
private String description;
}

View File

@ -0,0 +1,29 @@
package com.seer.teach.mp.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* <p>
* 活动表单模板DTO
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Schema(name = "ActivityFormTemplateDTO", description = "活动表单模板DTO")
@Data
public class ActivityFormTemplateDTO {
private Integer id;
@Schema(description = "表单模板名称")
private String templateName;
@Schema(description = "表单模板描述")
private String templateDescription;
@Schema(description = "状态0-禁用1-启用")
private Integer status;
}

View File

@ -0,0 +1,35 @@
package com.seer.teach.mp.api.dto;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
/**
* <p>
* 活动表单变量DTO
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Schema(name = "ActivityFormVariableDTO", description = "活动表单变量DTO")
@Data
public class ActivityFormVariableDTO {
private Integer id;
@Schema(description = "表单执行实例ID")
private Integer executionId;
@Schema(description = "变量名称")
private String variableName;
@Schema(description = "变量代码")
private String variableCode;
@Schema(description = "变量值")
private String variableValue;
@Schema(description = "数据类型string, number, boolean, json等")
private String dataType;
}

View File

@ -0,0 +1,50 @@
package com.seer.teach.mp.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.baomidou.mybatisplus.extension.handlers.JacksonTypeHandler;
import com.seer.teach.common.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.util.List;
/**
* <p>
* 活动表单模板表
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Getter
@Setter
@TableName(value = "mp_activity_form",autoResultMap = true)
@Schema(name = "MpActivityFormEntity对象", description = "活动表单表")
public class MpActivityFormEntity extends BaseEntity {
/**
* 表单名称
*/
@TableField("form_name")
private String formName;
/**
* 表单描述
*/
@TableField("form_description")
private String formDescription;
/**
* 配置
*/
@TableField("config")
private String config;
/**
* 字段列表
*/
@TableField(value = "fields",typeHandler = JacksonTypeHandler.class)
private List<String> fields;
}

View File

@ -0,0 +1,74 @@
package com.seer.teach.mp.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.seer.teach.common.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
import java.time.LocalDateTime;
/**
* <p>
* 活动表单执行实例表
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Getter
@Setter
@TableName("mp_activity_form_execution")
@Schema(name = "MpActivityFormExecutionEntity对象", description = "活动表单执行实例表")
public class MpActivityFormExecutionEntity extends BaseEntity {
/**
* 执行编号
*/
@TableField("execution_no")
private String executionNo;
/**
* 活动ID
*/
@TableField("activity_id")
private Integer activityId;
/**
* 代理商ID
*/
@TableField("agent_id")
private Integer agentId;
/**
* 使用的表单模板ID
*/
@TableField("form_id")
private Integer formId;
/**
* 提交人ID家长ID
*/
@TableField("submitter_id")
private Integer submitterId;
/**
* 提交人姓名
*/
@TableField("submitter_name")
private String submitterName;
/**
* 提交时间
*/
@TableField("submit_time")
private LocalDateTime submitTime;
/**
* 状态draft-草稿submitted-已提交approved-已批准rejected-已拒绝
*/
@TableField("status")
private String status;
}

View File

@ -0,0 +1,84 @@
package com.seer.teach.mp.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.seer.teach.common.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 活动表单字段定义表
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Getter
@Setter
@TableName("mp_activity_form_field")
@Schema(name = "MpActivityFormFieldEntity对象", description = "活动表单字段定义表")
public class MpActivityFormFieldEntity extends BaseEntity {
/**
* 所属模板ID
*/
@TableField("form_id")
private Integer formId;
/**
* 字段名称
*/
@TableField("field_name")
private String fieldName;
/**
* 字段代码英文标识
*/
@TableField("field_code")
private String fieldCode;
/**
* 字段类型text, textarea, select, radio, checkbox, date, number等
*/
@TableField("field_type")
private String fieldType;
/**
* 字段选项JSON格式适用于select, radio, checkbox等
*/
@TableField("field_options")
private String fieldOptions;
/**
* 占位符提示
*/
@TableField("placeholder")
private String placeholder;
/**
* 是否必填0-1-
*/
@TableField("is_required")
private Integer isRequired;
/**
* 排序
*/
@TableField("sort_order")
private Integer sortOrder;
/**
* 验证规则JSON格式
*/
@TableField("validation_rules")
private String validationRules;
/**
* 字段描述
*/
@TableField("description")
private String description;
}

View File

@ -0,0 +1,47 @@
package com.seer.teach.mp.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.seer.teach.common.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 活动与表单模板关联表
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Getter
@Setter
@TableName("mp_activity_form_relation")
@Schema(name = "MpActivityFormRelationEntity对象", description = "活动与表单模板关联表")
public class MpActivityFormRelationEntity extends BaseEntity {
/**
* 活动ID
*/
@TableField("activity_id")
private Integer activityId;
/**
* 表单模板ID
*/
@TableField("form_id")
private Integer formId;
/**
* 是否主要0-1-
*/
@TableField("is_primary")
private Integer isPrimary;
/**
* 版本,如1.0.0
*/
@TableField("version")
private String version;
}

View File

@ -0,0 +1,54 @@
package com.seer.teach.mp.entity;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.seer.teach.common.entity.BaseEntity;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Getter;
import lombok.Setter;
/**
* <p>
* 活动表单变量表
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Getter
@Setter
@TableName("mp_activity_form_variable")
@Schema(name = "MpActivityFormVariableEntity对象", description = "活动表单变量表")
public class MpActivityFormVariableEntity extends BaseEntity {
/**
* 表单执行实例ID
*/
@TableField("execution_id")
private Integer executionId;
/**
* 变量名称
*/
@TableField("variable_name")
private String variableName;
/**
* 变量代码
*/
@TableField("variable_code")
private String variableCode;
/**
* 变量值
*/
@TableField("variable_value")
private String variableValue;
/**
* 数据类型string, number, boolean, json等
*/
@TableField("data_type")
private String dataType;
}

View File

@ -0,0 +1,18 @@
package com.seer.teach.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.seer.teach.mp.entity.MpActivityFormExecutionEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 活动表单执行实例表 Mapper 接口
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Mapper
public interface MpActivityFormExecutionMapper extends BaseMapper<MpActivityFormExecutionEntity> {
}

View File

@ -0,0 +1,18 @@
package com.seer.teach.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.seer.teach.mp.entity.MpActivityFormFieldEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 活动表单字段定义表 Mapper 接口
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Mapper
public interface MpActivityFormFieldMapper extends BaseMapper<MpActivityFormFieldEntity> {
}

View File

@ -0,0 +1,18 @@
package com.seer.teach.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.seer.teach.mp.entity.MpActivityFormEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 活动表单模板表 Mapper 接口
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Mapper
public interface MpActivityFormMapper extends BaseMapper<MpActivityFormEntity> {
}

View File

@ -0,0 +1,18 @@
package com.seer.teach.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.seer.teach.mp.entity.MpActivityFormRelationEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 活动与表单模板关联表 Mapper 接口
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Mapper
public interface MpActivityFormRelationMapper extends BaseMapper<MpActivityFormRelationEntity> {
}

View File

@ -0,0 +1,18 @@
package com.seer.teach.mp.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.seer.teach.mp.entity.MpActivityFormVariableEntity;
import org.apache.ibatis.annotations.Mapper;
/**
* <p>
* 活动表单变量表 Mapper 接口
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Mapper
public interface MpActivityFormVariableMapper extends BaseMapper<MpActivityFormVariableEntity> {
}

View File

@ -0,0 +1,81 @@
package com.seer.teach.mp.admin.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.annotation.DecryptionAnnotation;
import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.mp.admin.controller.req.ActivityFormReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormResp;
import com.seer.teach.mp.admin.service.IAdminActivityFormService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* <p>
* 活动表单管理端控制器
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Tag(name = "ADMIN - 活动表单")
@RestController
@RequestMapping("/activity/form")
@LogPrint
@EncryptionAnnotation
@DecryptionAnnotation
@RequiredArgsConstructor
public class AdminActivityFormController {
private final IAdminActivityFormService adminActivityFormService;
@Operation(summary = "创建表单")
@PostMapping("/save")
@SaCheckPermission("mp:admin:activity:form:save")
public ResultBean<Boolean> save(@Valid @RequestBody ActivityFormReq request) {
Boolean result = adminActivityFormService.save(request);
return ResultBean.success(result);
}
@Operation(summary = "更新表单")
@PostMapping("/update")
@SaCheckPermission("mp:admin:activity:form:update")
public ResultBean<Boolean> update(@Valid @RequestBody ActivityFormReq request) {
Boolean result = adminActivityFormService.update(request);
return ResultBean.success(result);
}
@Operation(summary = "删除表单")
@DeleteMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:delete")
public ResultBean<Boolean> delete(@PathVariable Integer id) {
Boolean result = adminActivityFormService.deleteById(id);
return ResultBean.success(result);
}
@Operation(summary = "详情")
@GetMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:get")
public ResultBean<AdminActivityFormResp> get(@PathVariable Integer id) {
AdminActivityFormResp result = adminActivityFormService.getById(id);
return ResultBean.success(result);
}
@Operation(summary = "发布新版本")
@PostMapping("/publish-new-version")
@SaCheckPermission("mp:admin:activity:form:publish")
public ResultBean<Boolean> publishNewVersion(@RequestBody @Valid ActivityFormReq req) {
Boolean result = adminActivityFormService.publishNewVersion(req);
return ResultBean.success(result);
}
}

View File

@ -0,0 +1,77 @@
package com.seer.teach.mp.admin.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.annotation.DecryptionAnnotation;
import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.mp.admin.controller.req.ActivityFormExecutionQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormExecutionResp;
import com.seer.teach.mp.admin.service.IAdminActivityFormExecutionService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
/**
* <p>
* 活动表单执行实例管理端控制器
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Tag(name = "ADMIN - 活动表单执行实例")
@RestController
@RequestMapping("/activity/form/execution")
@LogPrint
@EncryptionAnnotation
@DecryptionAnnotation
@RequiredArgsConstructor
public class AdminActivityFormExecutionController {
private final IAdminActivityFormExecutionService adminActivityFormExecutionService;
@Operation(summary = "表单执行实例列表")
@PostMapping("/page-list")
@SaCheckPermission("mp:admin:activity:form:execution:list")
public ResultBean<PageListBean<AdminActivityFormExecutionResp>> pageList(@RequestBody @Valid ActivityFormExecutionQueryReq query) {
PageListBean<AdminActivityFormExecutionResp> result = adminActivityFormExecutionService.pageList(query);
return ResultBean.success(result);
}
@Operation(summary = "创建或更新表单执行实例")
@PostMapping("/save")
@SaCheckPermission("mp:admin:activity:form:execution:save")
public ResultBean<Boolean> save(@Valid @RequestBody ActivityFormExecutionQueryReq request) {
Boolean result = adminActivityFormExecutionService.saveOrUpdate(request);
return ResultBean.success(result);
}
@Operation(summary = "删除表单执行实例")
@DeleteMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:execution:delete")
public ResultBean<Boolean> delete(@PathVariable Integer id) {
Boolean result = adminActivityFormExecutionService.deleteById(id);
return ResultBean.success(result);
}
@Operation(summary = "详情")
@GetMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:execution:get")
public ResultBean<AdminActivityFormExecutionResp> get(@PathVariable Integer id) {
AdminActivityFormExecutionResp result = adminActivityFormExecutionService.getById(id);
return ResultBean.success(result);
}
@Operation(summary = "提交表单")
@PostMapping("/submit/{id}")
@SaCheckPermission("mp:admin:activity:form:execution:submit")
public ResultBean<Boolean> submit(@PathVariable Integer id) {
Boolean result = adminActivityFormExecutionService.submitById(id);
return ResultBean.success(result);
}
}

View File

@ -0,0 +1,78 @@
package com.seer.teach.mp.admin.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.annotation.DecryptionAnnotation;
import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.mp.admin.controller.req.ActivityFormFieldQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormFieldResp;
import com.seer.teach.mp.admin.service.IAdminActivityFormFieldService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import java.util.List;
/**
* <p>
* 活动表单字段管理端控制器
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Tag(name = "ADMIN - 活动表单字段")
@RestController
@RequestMapping("/activity/form/field")
@LogPrint
@EncryptionAnnotation
@DecryptionAnnotation
@RequiredArgsConstructor
public class AdminActivityFormFieldController {
private final IAdminActivityFormFieldService adminActivityFormFieldService;
@Operation(summary = "表单字段列表")
@PostMapping("/page-list")
@SaCheckPermission("mp:admin:activity:form:field:list")
public ResultBean<PageListBean<AdminActivityFormFieldResp>> pageList(@RequestBody @Valid ActivityFormFieldQueryReq query) {
PageListBean<AdminActivityFormFieldResp> result = adminActivityFormFieldService.pageList(query);
return ResultBean.success(result);
}
@Operation(summary = "创建或更新表单字段")
@PostMapping("/save")
@SaCheckPermission("mp:admin:activity:form:field:save")
public ResultBean<Boolean> save(@Valid @RequestBody ActivityFormFieldQueryReq request) {
Boolean result = adminActivityFormFieldService.saveOrUpdate(request);
return ResultBean.success(result);
}
@Operation(summary = "删除表单字段")
@DeleteMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:field:delete")
public ResultBean<Boolean> delete(@PathVariable Integer id) {
Boolean result = adminActivityFormFieldService.deleteById(id);
return ResultBean.success(result);
}
@Operation(summary = "详情")
@GetMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:field:get")
public ResultBean<AdminActivityFormFieldResp> get(@PathVariable Integer id) {
AdminActivityFormFieldResp result = adminActivityFormFieldService.getById(id);
return ResultBean.success(result);
}
@Operation(summary = "根据模板ID获取字段列表")
@GetMapping("/list-by-template/{templateId}")
@SaCheckPermission("mp:admin:activity:form:field:list")
public ResultBean<List<AdminActivityFormFieldResp>> listByTemplate(@PathVariable Integer templateId) {
List<AdminActivityFormFieldResp> result = adminActivityFormFieldService.listByTemplateId(templateId);
return ResultBean.success(result);
}
}

View File

@ -0,0 +1,63 @@
package com.seer.teach.mp.admin.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.annotation.DecryptionAnnotation;
import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormRelationResp;
import com.seer.teach.mp.admin.service.IAdminActivityFormRelationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* <p>
* 活动与表单关联管理端控制器
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Tag(name = "ADMIN - 活动与表单关联")
@RestController
@RequestMapping("/activity/form/relation")
@LogPrint
@EncryptionAnnotation
@DecryptionAnnotation
@RequiredArgsConstructor
public class AdminActivityFormRelationController {
private final IAdminActivityFormRelationService adminActivityFormRelationService;
@Operation(summary = "为活动关联表单")
@PostMapping("/associate")
@SaCheckPermission("mp:admin:activity:form:relation:associate")
public ResultBean<Boolean> associateFormWithActivity(
@RequestParam Integer activityId,
@RequestParam Integer templateId) {
Boolean result = adminActivityFormRelationService.associateFormWithActivity(activityId, templateId);
return ResultBean.success(result);
}
@Operation(summary = "解除活动与表单的关联")
@DeleteMapping("/disassociate")
@SaCheckPermission("mp:admin:activity:form:relation:disassociate")
public ResultBean<Boolean> disassociateFormWithActivity(
@RequestParam Integer activityId,
@RequestParam Integer templateId) {
Boolean result = adminActivityFormRelationService.disassociateFormWithActivity(activityId, templateId);
return ResultBean.success(result);
}
@Operation(summary = "获取活动关联的表单列表")
@GetMapping("/{activityId}")
@SaCheckPermission("mp:admin:activity:form:relation:list")
public ResultBean<List<AdminActivityFormRelationResp>> getFormsByActivity(@PathVariable Integer activityId) {
List<AdminActivityFormRelationResp> result = adminActivityFormRelationService.getFormsByActivity(activityId);
return ResultBean.success(result);
}
}

View File

@ -0,0 +1,78 @@
package com.seer.teach.mp.admin.controller;
import cn.dev33.satoken.annotation.SaCheckPermission;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.annotation.DecryptionAnnotation;
import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.mp.admin.controller.req.ActivityFormVariableQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormVariableResp;
import com.seer.teach.mp.admin.service.IAdminActivityFormVariableService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import jakarta.validation.Valid;
import java.util.List;
/**
* <p>
* 活动表单变量管理端控制器
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Tag(name = "ADMIN - 活动表单变量")
@RestController
@RequestMapping("/activity/form/variable")
@LogPrint
@EncryptionAnnotation
@DecryptionAnnotation
@RequiredArgsConstructor
public class AdminActivityFormVariableController {
private final IAdminActivityFormVariableService adminActivityFormVariableService;
@Operation(summary = "表单变量列表")
@PostMapping("/page-list")
@SaCheckPermission("mp:admin:activity:form:variable:list")
public ResultBean<PageListBean<AdminActivityFormVariableResp>> pageList(@RequestBody @Valid ActivityFormVariableQueryReq query) {
PageListBean<AdminActivityFormVariableResp> result = adminActivityFormVariableService.pageList(query);
return ResultBean.success(result);
}
@Operation(summary = "创建或更新表单变量")
@PostMapping("/save")
@SaCheckPermission("mp:admin:activity:form:variable:save")
public ResultBean<Boolean> save(@Valid @RequestBody ActivityFormVariableQueryReq request) {
Boolean result = adminActivityFormVariableService.saveOrUpdate(request);
return ResultBean.success(result);
}
@Operation(summary = "删除表单变量")
@DeleteMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:variable:delete")
public ResultBean<Boolean> delete(@PathVariable Integer id) {
Boolean result = adminActivityFormVariableService.deleteById(id);
return ResultBean.success(result);
}
@Operation(summary = "详情")
@GetMapping("/{id}")
@SaCheckPermission("mp:admin:activity:form:variable:get")
public ResultBean<AdminActivityFormVariableResp> get(@PathVariable Integer id) {
AdminActivityFormVariableResp result = adminActivityFormVariableService.getById(id);
return ResultBean.success(result);
}
@Operation(summary = "根据执行实例ID获取变量列表")
@GetMapping("/list-by-execution/{executionId}")
@SaCheckPermission("mp:admin:activity:form:variable:list")
public ResultBean<List<AdminActivityFormVariableResp>> listByExecution(@PathVariable Integer executionId) {
List<AdminActivityFormVariableResp> result = adminActivityFormVariableService.listByExecutionId(executionId);
return ResultBean.success(result);
}
}

View File

@ -0,0 +1,50 @@
package com.seer.teach.mp.admin.controller.req;
import com.seer.teach.common.request.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
import java.time.LocalDateTime;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "活动表单执行实例查询请求")
public class ActivityFormExecutionQueryReq extends PageRequest {
@Schema(description = "ID")
private Integer id;
@Schema(description = "执行编号")
@Size(max = 100, message = "执行编号长度不能超过100个字符")
private String executionNo;
@Schema(description = "活动ID")
@NotNull(message = "活动ID不能为空")
private Integer activityId;
@Schema(description = "代理商ID")
@NotNull(message = "代理商ID不能为空")
private Integer agentId;
@Schema(description = "使用的表单ID")
@NotNull(message = "表单ID不能为空")
private Integer formId;
@Schema(description = "提交人ID家长ID")
private Integer submitterId;
@Schema(description = "提交人姓名")
@Size(max = 255, message = "提交人姓名长度不能超过255个字符")
private String submitterName;
@Schema(description = "提交时间")
private LocalDateTime submitTime;
@Schema(description = "状态draft-草稿submitted-已提交approved-已批准rejected-已拒绝")
@Size(max = 50, message = "状态长度不能超过50个字符")
private String status;
}

View File

@ -0,0 +1,58 @@
package com.seer.teach.mp.admin.controller.req;
import com.seer.teach.common.request.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "活动表单字段查询请求")
public class ActivityFormFieldQueryReq extends PageRequest {
@Schema(description = "ID")
private Integer id;
@Schema(description = "所属ID")
@NotNull(message = "所属ID不能为空")
private Integer formId;
@Schema(description = "字段名称")
@NotBlank(message = "字段名称不能为空")
@Size(max = 255, message = "字段名称长度不能超过255个字符")
private String fieldName;
@Schema(description = "字段代码(英文标识)")
@NotBlank(message = "字段代码不能为空")
@Size(max = 100, message = "字段代码长度不能超过100个字符")
private String fieldCode;
@Schema(description = "字段类型text, textarea, select, radio, checkbox, date, number等")
@NotBlank(message = "字段类型不能为空")
@Size(max = 50, message = "字段类型长度不能超过50个字符")
private String fieldType;
@Schema(description = "字段选项JSON格式适用于select, radio, checkbox等")
private String fieldOptions;
@Schema(description = "占位符提示")
@Size(max = 500, message = "占位符提示长度不能超过500个字符")
private String placeholder;
@Schema(description = "是否必填0-否1-是")
private Integer isRequired;
@Schema(description = "排序")
private Integer sortOrder;
@Schema(description = "验证规则JSON格式")
private String validationRules;
@Schema(description = "字段描述")
private String description;
}

View File

@ -0,0 +1,15 @@
package com.seer.teach.mp.admin.controller.req;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
@Data
@Schema(description = "活动表单发布新版本请求")
public class ActivityFormPublishVersionReq {
@NotNull(message = "活动ID不能为空")
@Schema(description = "活动ID")
private Integer activityId;
}

View File

@ -0,0 +1,30 @@
package com.seer.teach.mp.admin.controller.req;
import com.seer.teach.common.request.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "活动表单模板查询请求")
public class ActivityFormQueryReq extends PageRequest {
@Schema(description = "ID")
private Integer id;
@Schema(description = "表单名称")
@NotBlank(message = "表单名称不能为空")
@Size(max = 255, message = "表单名称长度不能超过255个字符")
private String formName;
@Schema(description = "表单模板描述")
private String formDescription;
@Schema(description = "状态0-禁用1-启用")
private Integer status;
}

View File

@ -0,0 +1,40 @@
package com.seer.teach.mp.admin.controller.req;
import com.seer.teach.common.request.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.List;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "活动表单模板查询请求")
public class ActivityFormReq extends PageRequest {
@Schema(description = "ID")
private Integer id;
@Schema(description = "活动ID")
private Integer activityId;
@Schema(description = "表单名称")
@NotBlank(message = "表单名称不能为空")
@Size(max = 255, message = "表单名称长度不能超过255个字符")
private String formName;
@Schema(description = "表单模板描述")
private String formDescription;
@Schema(description = "状态0-禁用1-启用")
private Integer status;
@Schema(description = "表单配置")
private String config;
@Schema(description = "表单字段")
private List<String> fields;
}

View File

@ -0,0 +1,38 @@
package com.seer.teach.mp.admin.controller.req;
import com.seer.teach.common.request.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "活动表单变量查询请求")
public class ActivityFormVariableQueryReq extends PageRequest {
@Schema(description = "ID")
private Integer id;
@Schema(description = "表单执行实例ID")
@NotNull(message = "表单执行实例ID不能为空")
private Integer executionId;
@Schema(description = "变量名称")
@Size(max = 255, message = "变量名称长度不能超过255个字符")
private String variableName;
@Schema(description = "变量代码")
@Size(max = 100, message = "变量代码长度不能超过100个字符")
private String variableCode;
@Schema(description = "变量值")
private String variableValue;
@Schema(description = "数据类型string, number, boolean, json等")
@Size(max = 50, message = "数据类型长度不能超过50个字符")
private String dataType;
}

View File

@ -0,0 +1,46 @@
package com.seer.teach.mp.admin.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(name = "AdminActivityFormExecutionResp", description = "活动表单执行实例响应参数")
@Data
public class AdminActivityFormExecutionResp {
private Integer id;
@Schema(description = "执行编号")
private String executionNo;
@Schema(description = "活动ID")
private Integer activityId;
@Schema(description = "代理商ID")
private Integer agentId;
@Schema(description = "使用的表单ID")
private Integer formId;
@Schema(description = "提交人ID家长ID")
private Integer submitterId;
@Schema(description = "提交人姓名")
private String submitterName;
@Schema(description = "提交时间")
private LocalDateTime submitTime;
@Schema(description = "状态draft-草稿submitted-已提交approved-已批准rejected-已拒绝")
private String status;
@Schema(description = "创建人ID")
private Integer creatorId;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,52 @@
package com.seer.teach.mp.admin.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(name = "AdminActivityFormFieldResp", description = "活动表单字段响应参数")
@Data
public class AdminActivityFormFieldResp {
private Integer id;
@Schema(description = "所属表单ID")
private Integer formId;
@Schema(description = "字段名称")
private String fieldName;
@Schema(description = "字段代码(英文标识)")
private String fieldCode;
@Schema(description = "字段类型text, textarea, select, radio, checkbox, date, number等")
private String fieldType;
@Schema(description = "字段选项JSON格式适用于select, radio, checkbox等")
private String fieldOptions;
@Schema(description = "占位符提示")
private String placeholder;
@Schema(description = "是否必填0-否1-是")
private Integer isRequired;
@Schema(description = "排序")
private Integer sortOrder;
@Schema(description = "验证规则JSON格式")
private String validationRules;
@Schema(description = "字段描述")
private String description;
@Schema(description = "创建人ID")
private Integer creatorId;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,55 @@
package com.seer.teach.mp.admin.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(name = "AdminActivityFormRelationResp", description = "活动表单模板响应参数")
@Data
public class AdminActivityFormRelationResp {
/**
* 活动ID
*/
@Schema(description = "活动ID")
private Integer activityId;
/**
* 表单模板ID
*/
@Schema(description = "表单ID")
private Integer formId;
/**
* 是否主要0-1-
*/
@Schema(description = "是否主要0-否1-是")
private Integer isPrimary;
/**
* 版本,如1.0.0
*/
@Schema(description = "版本,如1.0.0")
private String version;
/**
* 表单名称
*/
@Schema(description = "表单名称")
private String formName;
/**
* 表单描述
*/
@Schema(description = "表单描述")
private String fromDescription;
/**
* 状态0-禁用1-启用
*/
@Schema(description = "状态0-禁用1-启用")
private Integer status;
}

View File

@ -0,0 +1,42 @@
package com.seer.teach.mp.admin.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(name = "AdminActivityFormResp", description = "活动表单响应参数")
@Data
public class AdminActivityFormResp {
/**
* 表单ID
*/
@Schema(description = "表单ID")
private Integer id;
/**
* 活动ID
*/
@Schema(description = "活动ID")
private Integer activityId;
/**
* 表单名称
*/
@Schema(description = "表单名称")
private String formName;
/**
* 表单描述
*/
@Schema(description = "表单描述")
private String fromDescription;
/**
* 表单字段
*/
@Schema(description = "表单字段")
private List<String> fields;
}

View File

@ -0,0 +1,37 @@
package com.seer.teach.mp.admin.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
@Schema(name = "AdminActivityFormVariableResp", description = "活动表单变量响应参数")
@Data
public class AdminActivityFormVariableResp {
private Integer id;
@Schema(description = "表单执行实例ID")
private Integer executionId;
@Schema(description = "变量名称")
private String variableName;
@Schema(description = "变量代码")
private String variableCode;
@Schema(description = "变量值")
private String variableValue;
@Schema(description = "数据类型string, number, boolean, json等")
private String dataType;
@Schema(description = "创建人ID")
private Integer creatorId;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,20 @@
package com.seer.teach.mp.admin.convert;
import com.seer.teach.mp.admin.controller.req.ActivityFormReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormRelationResp;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormResp;
import com.seer.teach.mp.entity.MpActivityFormEntity;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminActivityFormConvert {
AdminActivityFormConvert INSTANCE = Mappers.getMapper(AdminActivityFormConvert.class);
AdminActivityFormResp convertToResp(MpActivityFormEntity entity);
AdminActivityFormRelationResp convertToRelationResp(MpActivityFormEntity entity);
MpActivityFormEntity convertToEntity(ActivityFormReq request);
}

View File

@ -0,0 +1,15 @@
package com.seer.teach.mp.admin.convert;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormExecutionResp;
import com.seer.teach.mp.entity.MpActivityFormExecutionEntity;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminActivityFormExecutionConvert {
AdminActivityFormExecutionConvert INSTANCE = Mappers.getMapper(AdminActivityFormExecutionConvert.class);
AdminActivityFormExecutionResp convertToResp(MpActivityFormExecutionEntity entity);
}

View File

@ -0,0 +1,14 @@
package com.seer.teach.mp.admin.convert;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormFieldResp;
import com.seer.teach.mp.entity.MpActivityFormFieldEntity;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminActivityFormFieldConvert {
AdminActivityFormFieldConvert INSTANCE = Mappers.getMapper(AdminActivityFormFieldConvert.class);
AdminActivityFormFieldResp convertToResp(MpActivityFormFieldEntity entity);
}

View File

@ -0,0 +1,20 @@
package com.seer.teach.mp.admin.convert;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormVariableResp;
import com.seer.teach.mp.entity.MpActivityFormVariableEntity;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AdminActivityFormVariableConvert {
AdminActivityFormVariableConvert INSTANCE = Mappers.getMapper(AdminActivityFormVariableConvert.class);
@Mapping(source = "id", target = "id")
@Mapping(source = "executionId", target = "executionId")
@Mapping(source = "variableName", target = "variableName")
@Mapping(source = "variableCode", target = "variableCode")
@Mapping(source = "variableValue", target = "variableValue")
@Mapping(source = "dataType", target = "dataType")
AdminActivityFormVariableResp convertToResp(MpActivityFormVariableEntity entity);
}

View File

@ -0,0 +1,25 @@
package com.seer.teach.mp.admin.convert;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormRelationResp;
import com.seer.teach.mp.entity.MpActivityFormRelationEntity;
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;
import java.util.List;
@Mapper
public interface AdminMpActivityFormRelationConvert {
AdminMpActivityFormRelationConvert INSTANCE = Mappers.getMapper(AdminMpActivityFormRelationConvert.class);
/**
* 转换
*
* @param entity
* @return
*/
AdminActivityFormRelationResp toAdminActivityFormRelationResp(MpActivityFormRelationEntity entity);
List<AdminActivityFormRelationResp> toAdminActivityFormRelationRespList(List<MpActivityFormRelationEntity> entityList);
}

View File

@ -0,0 +1,56 @@
package com.seer.teach.mp.admin.service;
import com.seer.teach.common.PageListBean;
import com.seer.teach.mp.admin.controller.req.ActivityFormExecutionQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormExecutionResp;
/**
* <p>
* 管理端活动表单执行实例服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IAdminActivityFormExecutionService {
/**
* 分页查询活动表单执行实例
*
* @param query 查询参数
* @return 分页结果
*/
PageListBean<AdminActivityFormExecutionResp> pageList(ActivityFormExecutionQueryReq query);
/**
* 保存或更新活动表单执行实例
*
* @param request 请求参数
* @return 操作结果
*/
Boolean saveOrUpdate(ActivityFormExecutionQueryReq request);
/**
* 删除活动表单执行实例
*
* @param id 实例ID
* @return 操作结果
*/
Boolean deleteById(Integer id);
/**
* 根据ID获取活动表单执行实例
*
* @param id 实例ID
* @return 实例信息
*/
AdminActivityFormExecutionResp getById(Integer id);
/**
* 提交表单
*
* @param id 实例ID
* @return 操作结果
*/
Boolean submitById(Integer id);
}

View File

@ -0,0 +1,58 @@
package com.seer.teach.mp.admin.service;
import com.seer.teach.common.PageListBean;
import com.seer.teach.mp.admin.controller.req.ActivityFormFieldQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormFieldResp;
import java.util.List;
/**
* <p>
* 管理端活动表单字段服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IAdminActivityFormFieldService {
/**
* 分页查询活动表单字段
*
* @param query 查询参数
* @return 分页结果
*/
PageListBean<AdminActivityFormFieldResp> pageList(ActivityFormFieldQueryReq query);
/**
* 保存或更新活动表单字段
*
* @param request 请求参数
* @return 操作结果
*/
Boolean saveOrUpdate(ActivityFormFieldQueryReq request);
/**
* 删除活动表单字段
*
* @param id 字段ID
* @return 操作结果
*/
Boolean deleteById(Integer id);
/**
* 根据ID获取活动表单字段
*
* @param id 字段ID
* @return 字段信息
*/
AdminActivityFormFieldResp getById(Integer id);
/**
* 根据模板ID获取字段列表
*
* @param templateId 模板ID
* @return 字段列表
*/
List<AdminActivityFormFieldResp> listByTemplateId(Integer templateId);
}

View File

@ -0,0 +1,43 @@
package com.seer.teach.mp.admin.service;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormRelationResp;
import java.util.List;
/**
* <p>
* 管理端活动与表单关联服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IAdminActivityFormRelationService {
/**
* 为活动关联表单
*
* @param activityId 活动ID
* @param formId 表单ID
* @return 操作结果
*/
Boolean associateFormWithActivity(Integer activityId, Integer formId);
/**
* 解除活动与表单的关联
*
* @param activityId 表单ID
* @param formId ID
* @return 操作结果
*/
Boolean disassociateFormWithActivity(Integer activityId, Integer formId);
/**
* 获取活动关联的表单列表
*
* @param activityId 活动ID
* @return 表单列表
*/
List<AdminActivityFormRelationResp> getFormsByActivity(Integer activityId);
}

View File

@ -0,0 +1,58 @@
package com.seer.teach.mp.admin.service;
import com.seer.teach.common.PageListBean;
import com.seer.teach.mp.admin.controller.req.ActivityFormQueryReq;
import com.seer.teach.mp.admin.controller.req.ActivityFormReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormRelationResp;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormResp;
/**
* <p>
* 管理端活动表单模板服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IAdminActivityFormService {
/**
* 保存活动表单模板
*
* @param request 请求参数
* @return 操作结果
*/
Boolean save(ActivityFormReq request);
/**
* 删除活动表单模板
*
* @param id 模板ID
* @return 操作结果
*/
Boolean deleteById(Integer id);
/**
* 根据ID获取活动表单模板
*
* @param id 模板ID
* @return 模板信息
*/
AdminActivityFormResp getById(Integer id);
/**
* 更新活动表单模板
*
* @param request 模板信息
* @return 操作结果
*/
Boolean update(ActivityFormReq request);
/**
* 发布新版本
*
* @param req 请求参数
* @return 操作结果
*/
Boolean publishNewVersion(ActivityFormReq req);
}

View File

@ -0,0 +1,58 @@
package com.seer.teach.mp.admin.service;
import com.seer.teach.common.PageListBean;
import com.seer.teach.mp.admin.controller.req.ActivityFormVariableQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormVariableResp;
import java.util.List;
/**
* <p>
* 管理端活动表单变量服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IAdminActivityFormVariableService {
/**
* 分页查询活动表单变量
*
* @param query 查询参数
* @return 分页结果
*/
PageListBean<AdminActivityFormVariableResp> pageList(ActivityFormVariableQueryReq query);
/**
* 保存或更新活动表单变量
*
* @param request 请求参数
* @return 操作结果
*/
Boolean saveOrUpdate(ActivityFormVariableQueryReq request);
/**
* 删除活动表单变量
*
* @param id 变量ID
* @return 操作结果
*/
Boolean deleteById(Integer id);
/**
* 根据ID获取活动表单变量
*
* @param id 变量ID
* @return 变量信息
*/
AdminActivityFormVariableResp getById(Integer id);
/**
* 根据执行实例ID获取变量列表
*
* @param executionId 执行实例ID
* @return 变量列表
*/
List<AdminActivityFormVariableResp> listByExecutionId(Integer executionId);
}

View File

@ -0,0 +1,90 @@
package com.seer.teach.mp.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mp.admin.controller.req.ActivityFormExecutionQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormExecutionResp;
import com.seer.teach.mp.admin.convert.AdminActivityFormExecutionConvert;
import com.seer.teach.mp.admin.service.IAdminActivityFormExecutionService;
import com.seer.teach.mp.entity.MpActivityFormExecutionEntity;
import com.seer.teach.mp.service.IMpActivityFormExecutionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
/**
* <p>
* 管理端活动表单执行实例服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminActivityFormExecutionServiceImpl implements IAdminActivityFormExecutionService {
private final IMpActivityFormExecutionService activityFormExecutionService;
@Override
public PageListBean<AdminActivityFormExecutionResp> pageList(ActivityFormExecutionQueryReq query) {
Page<MpActivityFormExecutionEntity> page = new Page<>(query.getPageNo(), query.getPageSize());
LambdaQueryWrapper<MpActivityFormExecutionEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(query.getActivityId() != null, MpActivityFormExecutionEntity::getActivityId, query.getActivityId())
.eq(query.getAgentId() != null, MpActivityFormExecutionEntity::getAgentId, query.getAgentId())
.eq(query.getFormId() != null, MpActivityFormExecutionEntity::getFormId, query.getFormId())
.eq(StringUtils.isNotBlank(query.getStatus()),
MpActivityFormExecutionEntity::getStatus, query.getStatus())
.like(StringUtils.isNotBlank(query.getSubmitterName()),
MpActivityFormExecutionEntity::getSubmitterName, query.getSubmitterName())
.orderByDesc(MpActivityFormExecutionEntity::getId);
Page<MpActivityFormExecutionEntity> pageResult = activityFormExecutionService.page(page, wrapper);
return PageConverterUtils.convertPageList(pageResult, AdminActivityFormExecutionConvert.INSTANCE::convertToResp);
}
@Override
public Boolean saveOrUpdate(ActivityFormExecutionQueryReq request) {
MpActivityFormExecutionEntity entity = new MpActivityFormExecutionEntity();
BeanUtil.copyProperties(request, entity);
if (request.getId() == null) {
// 新增时设置默认值
entity.setStatus(entity.getStatus() == null ? "draft" : entity.getStatus());
}
return activityFormExecutionService.saveOrUpdate(entity);
}
@Override
public Boolean deleteById(Integer id) {
return activityFormExecutionService.removeById(id);
}
@Override
public AdminActivityFormExecutionResp getById(Integer id) {
if (id == null) {
return null;
}
MpActivityFormExecutionEntity entity = activityFormExecutionService.getById(id);
return AdminActivityFormExecutionConvert.INSTANCE.convertToResp(entity);
}
@Override
public Boolean submitById(Integer id) {
MpActivityFormExecutionEntity entity = activityFormExecutionService.getById(id);
if (entity == null) {
return false;
}
entity.setStatus("submitted");
return activityFormExecutionService.updateById(entity);
}
}

View File

@ -0,0 +1,99 @@
package com.seer.teach.mp.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mp.admin.controller.req.ActivityFormFieldQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormFieldResp;
import com.seer.teach.mp.admin.convert.AdminActivityFormFieldConvert;
import com.seer.teach.mp.admin.service.IAdminActivityFormFieldService;
import com.seer.teach.mp.entity.MpActivityFormFieldEntity;
import com.seer.teach.mp.service.IMpActivityFormFieldService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 管理端活动表单字段服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminActivityFormFieldServiceImpl implements IAdminActivityFormFieldService {
private final IMpActivityFormFieldService activityFormFieldService;
@Override
public PageListBean<AdminActivityFormFieldResp> pageList(ActivityFormFieldQueryReq query) {
Page<MpActivityFormFieldEntity> page = new Page<>(query.getPageNo(), query.getPageSize());
LambdaQueryWrapper<MpActivityFormFieldEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(query.getFormId() != null, MpActivityFormFieldEntity::getFormId, query.getFormId())
.like(StringUtils.isNotBlank(query.getFieldName()),
MpActivityFormFieldEntity::getFieldName, query.getFieldName())
.eq(StringUtils.isNotBlank(query.getFieldType()),
MpActivityFormFieldEntity::getFieldType, query.getFieldType())
.orderByAsc(MpActivityFormFieldEntity::getSortOrder)
.orderByDesc(MpActivityFormFieldEntity::getId);
Page<MpActivityFormFieldEntity> pageResult = activityFormFieldService.page(page, wrapper);
return PageConverterUtils.convertPageList(pageResult, AdminActivityFormFieldConvert.INSTANCE::convertToResp);
}
@Override
public Boolean saveOrUpdate(ActivityFormFieldQueryReq request) {
MpActivityFormFieldEntity entity = new MpActivityFormFieldEntity();
BeanUtil.copyProperties(request, entity);
if (request.getId() == null) {
// 新增时设置默认值
entity.setIsRequired(entity.getIsRequired() == null ? 0 : entity.getIsRequired());
entity.setSortOrder(entity.getSortOrder() == null ? 0 : entity.getSortOrder());
}
return activityFormFieldService.saveOrUpdate(entity);
}
@Override
public Boolean deleteById(Integer id) {
return activityFormFieldService.removeById(id);
}
@Override
public AdminActivityFormFieldResp getById(Integer id) {
if (id == null) {
return null;
}
MpActivityFormFieldEntity entity = activityFormFieldService.getById(id);
return AdminActivityFormFieldConvert.INSTANCE.convertToResp(entity);
}
@Override
public List<AdminActivityFormFieldResp> listByTemplateId(Integer templateId) {
if (templateId == null) {
return java.util.Collections.emptyList();
}
List<MpActivityFormFieldEntity> entities = activityFormFieldService.list(
new LambdaQueryWrapper<MpActivityFormFieldEntity>()
.eq(MpActivityFormFieldEntity::getFormId, templateId)
.orderByAsc(MpActivityFormFieldEntity::getSortOrder)
.orderByDesc(MpActivityFormFieldEntity::getId)
);
return entities.stream()
.map(AdminActivityFormFieldConvert.INSTANCE::convertToResp)
.collect(Collectors.toList());
}
}

View File

@ -0,0 +1,90 @@
package com.seer.teach.mp.admin.service.impl;
import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormRelationResp;
import com.seer.teach.mp.admin.convert.AdminMpActivityFormRelationConvert;
import com.seer.teach.mp.admin.service.IAdminActivityFormRelationService;
import com.seer.teach.mp.entity.MpActivityFormEntity;
import com.seer.teach.mp.entity.MpActivityFormRelationEntity;
import com.seer.teach.mp.service.IMpActivityFormRelationService;
import com.seer.teach.mp.service.IMpActivityFormService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
* <p>
* 管理端活动与表单模板关联服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminActivityFormRelationServiceImpl implements IAdminActivityFormRelationService {
private final IMpActivityFormRelationService activityFormTemplateRelationService;
private final IMpActivityFormService activityFormTemplateService;
@Override
public Boolean associateFormWithActivity(Integer activityId, Integer formId) {
return activityFormTemplateRelationService.createRelation(activityId, formId);
}
@Override
public Boolean disassociateFormWithActivity(Integer activityId, Integer formId) {
return activityFormTemplateRelationService.remove(
new LambdaQueryWrapper<MpActivityFormRelationEntity>()
.eq(MpActivityFormRelationEntity::getActivityId, activityId)
.eq(MpActivityFormRelationEntity::getFormId, formId)
);
}
@Override
public List<AdminActivityFormRelationResp> getFormsByActivity(Integer activityId) {
if (activityId == null) {
return java.util.Collections.emptyList();
}
List<MpActivityFormRelationEntity> relations = activityFormTemplateRelationService.list(
new LambdaQueryWrapper<MpActivityFormRelationEntity>()
.eq(MpActivityFormRelationEntity::getActivityId, activityId)
);
if(CollectionUtil.isEmpty(relations)){
return Collections.emptyList();
}
List<Integer> formIds = relations.stream()
.map(MpActivityFormRelationEntity::getFormId)
.collect(java.util.stream.Collectors.toList());
List<MpActivityFormEntity> forms = activityFormTemplateService.list(
new LambdaQueryWrapper<MpActivityFormEntity>()
.in(MpActivityFormEntity::getId, formIds)
);
log.info("getFormsByActivity: {}", forms);
if(CollectionUtil.isEmpty(forms)){
return Collections.emptyList();
}
Map<Integer, MpActivityFormEntity> mapping = forms.stream().collect(Collectors.toMap(MpActivityFormEntity::getId, Function.identity(), (old, newOne) -> newOne));
List<AdminActivityFormRelationResp> adminActivityFormRelationRespList = AdminMpActivityFormRelationConvert.INSTANCE.toAdminActivityFormRelationRespList(relations);
for (AdminActivityFormRelationResp adminActivityFormRelationResp : adminActivityFormRelationRespList) {
MpActivityFormEntity activityForm = mapping.get(adminActivityFormRelationResp.getFormId());
if(Objects.nonNull(activityForm)){
adminActivityFormRelationResp.setFormName(activityForm.getFormName());
adminActivityFormRelationResp.setFromDescription(activityForm.getFormDescription());
}
}
log.debug("getFormsByActivity: {}", adminActivityFormRelationRespList);
return adminActivityFormRelationRespList;
}
}

View File

@ -0,0 +1,109 @@
package com.seer.teach.mp.admin.service.impl;
import com.seer.teach.common.constants.CommonConstant;
import com.seer.teach.common.utils.CommonUtils;
import com.seer.teach.mp.admin.controller.req.ActivityFormReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormResp;
import com.seer.teach.mp.admin.convert.AdminActivityFormConvert;
import com.seer.teach.mp.admin.service.IAdminActivityFormService;
import com.seer.teach.mp.entity.MpActivityFormEntity;
import com.seer.teach.mp.entity.MpActivityFormRelationEntity;
import com.seer.teach.mp.service.IMpActivityFormRelationService;
import com.seer.teach.mp.service.IMpActivityFormService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Optional;
/**
* <p>
* 管理端活动表单模板服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminActivityFormServiceImpl implements IAdminActivityFormService {
private final IMpActivityFormService activityFormService;
private final IMpActivityFormRelationService activityFormRelationService;
@Override
public Boolean save(ActivityFormReq request) {
MpActivityFormEntity form = AdminActivityFormConvert.INSTANCE.convertToEntity(request);
boolean saveResult = activityFormService.save(form);
if (saveResult) {
MpActivityFormRelationEntity relation = new MpActivityFormRelationEntity();
relation.setActivityId(request.getActivityId());
relation.setFormId(form.getId());
Optional<MpActivityFormRelationEntity> optionalRelation = activityFormRelationService.getLatestVersionByActivityId(request.getActivityId());
if (optionalRelation.isPresent()) {
relation.setIsPrimary(CommonConstant.IS_NOT_DEFAULT);
relation.setVersion(CommonUtils.generateVersionNumber(optionalRelation.get().getVersion()));
} else {
relation.setIsPrimary(CommonConstant.IS_DEFAULT);
relation.setVersion("1.0.0");
}
boolean saved = activityFormRelationService.save(relation);
log.info("保存关联关系:{}", saved);
}
return saveResult;
}
@Override
public Boolean deleteById(Integer id) {
return activityFormService.removeById(id);
}
@Override
public AdminActivityFormResp getById(Integer id) {
if (id == null) {
return null;
}
MpActivityFormEntity entity = activityFormService.getById(id);
return AdminActivityFormConvert.INSTANCE.convertToResp(entity);
}
@Override
public Boolean update(ActivityFormReq request) {
if (request.getId() == null) {
return false;
}
MpActivityFormEntity form = AdminActivityFormConvert.INSTANCE.convertToEntity(request);
return activityFormService.updateById(form);
}
@Override
public Boolean publishNewVersion(ActivityFormReq req) {
Integer activityId = req.getActivityId();
if (activityId == null) {
return false;
}
Optional<MpActivityFormRelationEntity> optionalRelation = activityFormRelationService.getLatestVersionByActivityId(activityId);
if (optionalRelation.isEmpty()) {
return false;
}
MpActivityFormRelationEntity latestRelation = optionalRelation.get();
// 复制当前表单信息创建新版本
MpActivityFormEntity newForm = AdminActivityFormConvert.INSTANCE.convertToEntity(req);
// 保存新的表单记录
boolean saved = activityFormService.save(newForm);
if (!saved) {
log.error("publishNewVersion失败:{}", newForm);
return false;
}
MpActivityFormRelationEntity newRelation = new MpActivityFormRelationEntity();
newRelation.setActivityId(req.getActivityId());
newRelation.setFormId(req.getId());
newRelation.setIsPrimary(CommonConstant.IS_NOT_DEFAULT);
newRelation.setVersion(CommonUtils.generateVersionNumber(latestRelation.getVersion()));
return activityFormRelationService.save(newRelation);
}
}

View File

@ -0,0 +1,96 @@
package com.seer.teach.mp.admin.service.impl;
import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mp.admin.controller.req.ActivityFormVariableQueryReq;
import com.seer.teach.mp.admin.controller.resp.AdminActivityFormVariableResp;
import com.seer.teach.mp.admin.convert.AdminActivityFormVariableConvert;
import com.seer.teach.mp.admin.service.IAdminActivityFormVariableService;
import com.seer.teach.mp.entity.MpActivityFormVariableEntity;
import com.seer.teach.mp.service.IMpActivityFormVariableService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* <p>
* 管理端活动表单变量服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminActivityFormVariableServiceImpl implements IAdminActivityFormVariableService {
private final IMpActivityFormVariableService activityFormVariableService;
@Override
public PageListBean<AdminActivityFormVariableResp> pageList(ActivityFormVariableQueryReq query) {
Page<MpActivityFormVariableEntity> page = new Page<>(query.getPageNo(), query.getPageSize());
LambdaQueryWrapper<MpActivityFormVariableEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(query.getExecutionId() != null, MpActivityFormVariableEntity::getExecutionId, query.getExecutionId())
.eq(StringUtils.isNotBlank(query.getVariableCode()),
MpActivityFormVariableEntity::getVariableCode, query.getVariableCode())
.like(StringUtils.isNotBlank(query.getVariableName()),
MpActivityFormVariableEntity::getVariableName, query.getVariableName())
.orderByDesc(MpActivityFormVariableEntity::getId);
Page<MpActivityFormVariableEntity> pageResult = activityFormVariableService.page(page, wrapper);
List<AdminActivityFormVariableResp> records = pageResult.getRecords().stream()
.map(AdminActivityFormVariableConvert.INSTANCE::convertToResp)
.collect(Collectors.toList());
return PageConverterUtils.convertPageListBean(pageResult, records);
}
@Override
public Boolean saveOrUpdate(ActivityFormVariableQueryReq request) {
MpActivityFormVariableEntity entity = new MpActivityFormVariableEntity();
BeanUtil.copyProperties(request, entity);
if (request.getId() == null) {
// 新增时设置默认值
entity.setDataType(entity.getDataType() == null ? "string" : entity.getDataType());
}
return activityFormVariableService.saveOrUpdate(entity);
}
@Override
public Boolean deleteById(Integer id) {
return activityFormVariableService.removeById(id);
}
@Override
public AdminActivityFormVariableResp getById(Integer id) {
MpActivityFormVariableEntity entity = activityFormVariableService.getById(id);
return AdminActivityFormVariableConvert.INSTANCE.convertToResp(entity);
}
@Override
public List<AdminActivityFormVariableResp> listByExecutionId(Integer executionId) {
if (executionId == null) {
return java.util.Collections.emptyList();
}
List<MpActivityFormVariableEntity> entities = activityFormVariableService.list(
new LambdaQueryWrapper<MpActivityFormVariableEntity>()
.eq(MpActivityFormVariableEntity::getExecutionId, executionId)
.orderByDesc(MpActivityFormVariableEntity::getId)
);
return entities.stream()
.map(AdminActivityFormVariableConvert.INSTANCE::convertToResp)
.collect(Collectors.toList());
}
}

View File

@ -138,6 +138,7 @@ CREATE TABLE `mp_activity_info_collection` (
`region` varchar(255) COMMENT '地区',
`parent_identity` varchar(20) COMMENT '家长身份(爸爸,妈妈)',
`learning_situation` varchar(20) COMMENT '学习情况(优、良、中、差)',
`contact_call_count` int NOT NULL DEFAULT 0 COMMENT '代理商拨打电话联系家长次数',
`weak_subject_ids` varchar(50) COMMENT '薄弱科目',
`strong_subject_ids` varchar(50) COMMENT '优势科目',
`weak_subject` varchar(50) COMMENT '偏科(数学、英语等)',

View File

@ -0,0 +1,105 @@
-- 创建表单表
DROP TABLE IF EXISTS `mp_activity_form`;
CREATE TABLE `mp_activity_form` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`form_name` varchar(255) NOT NULL COMMENT '表单名称',
`form_description` text COMMENT '表单描述',
`config` text COMMENT '表单的配置信息',
`fields` text COMMENT '表单项的数组',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '修改人',
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` varchar(20) DEFAULT 'Default' COMMENT '租户id',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='活动表单表';
-- 创建表单字段定义表
DROP TABLE IF EXISTS `mp_activity_form_field`;
CREATE TABLE `mp_activity_form_field` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`form_id` int NOT NULL COMMENT '所属ID',
`field_name` varchar(255) NOT NULL COMMENT '字段名称',
`field_code` varchar(100) NOT NULL COMMENT '字段代码(英文标识)',
`field_type` varchar(50) NOT NULL COMMENT '字段类型text, textarea, select, radio, checkbox, date, number等',
`field_options` text COMMENT '字段选项JSON格式适用于select, radio, checkbox等',
`placeholder` varchar(500) DEFAULT NULL COMMENT '占位符提示',
`is_required` tinyint NOT NULL DEFAULT '0' COMMENT '是否必填0-否1-是',
`sort_order` int DEFAULT '0' COMMENT '排序',
`validation_rules` text COMMENT '验证规则JSON格式',
`description` text COMMENT '字段描述',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '修改人',
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` varchar(20) DEFAULT 'Default' COMMENT '租户id',
PRIMARY KEY (`id`),
KEY `idx_form_id` (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='活动表单字段定义表';
-- 创建表单执行实例表
DROP TABLE IF EXISTS `mp_activity_form_execution`;
CREATE TABLE `mp_activity_form_execution` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`execution_no` varchar(100) NOT NULL COMMENT '执行编号',
`activity_id` int NOT NULL COMMENT '活动ID',
`agent_id` int NOT NULL COMMENT '代理商ID',
`form_id` int NOT NULL COMMENT '使用的表单ID',
`submitter_id` int DEFAULT NULL COMMENT '提交人ID家长ID',
`submitter_name` varchar(255) DEFAULT NULL COMMENT '提交人姓名',
`submit_time` datetime DEFAULT NULL COMMENT '提交时间',
`status` varchar(50) NOT NULL DEFAULT 'draft' COMMENT '状态draft-草稿submitted-已提交approved-已批准rejected-已拒绝',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '修改人',
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` varchar(20) DEFAULT 'Default' COMMENT '租户id',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_execution_no` (`execution_no`),
KEY `idx_activity_id` (`activity_id`),
KEY `idx_agent_id` (`agent_id`),
KEY `idx_form_id` (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='活动表单执行实例表';
-- 创建表单变量表
DROP TABLE IF EXISTS `mp_activity_form_variable`;
CREATE TABLE `mp_activity_form_variable` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`execution_id` int NOT NULL COMMENT '表单执行实例ID',
`variable_name` varchar(255) NOT NULL COMMENT '变量名称',
`variable_code` varchar(100) NOT NULL COMMENT '变量代码',
`variable_value` text NOT NULL COMMENT '变量值',
`data_type` varchar(50) DEFAULT 'string' COMMENT '数据类型string, number, boolean, json等',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '修改人',
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` varchar(20) DEFAULT 'Default' COMMENT '租户id',
PRIMARY KEY (`id`),
KEY `idx_execution_id` (`execution_id`),
KEY `idx_variable_code` (`variable_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='活动表单变量表';
-- 创建活动与表单关联表
DROP TABLE IF EXISTS `mp_activity_form_relation`;
CREATE TABLE `mp_activity_form_relation` (
`id` int NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`activity_id` int NOT NULL COMMENT '活动ID',
`form_id` int NOT NULL COMMENT '表单ID',
`is_primary` tinyint NOT NULL DEFAULT '0' COMMENT '是否主要0-否1-是',
`version` varchar(32) NOT NULL DEFAULT '1.0.0' COMMENT '版本号',
`create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间',
`create_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '创建人',
`update_by` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_german2_ci NULL DEFAULT NULL COMMENT '修改人',
`deleted` bit(1) NULL DEFAULT b'0' COMMENT '是否删除',
`tenant_id` varchar(20) DEFAULT 'Default' COMMENT '租户id',
PRIMARY KEY (`id`),
UNIQUE KEY `uk_activity_template` (`activity_id`, `form_id`),
KEY `idx_activity_id` (`activity_id`),
KEY `idx_form_id` (`form_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci COMMENT='活动与表单关联表';

View File

@ -0,0 +1,90 @@
package com.seer.teach.mp.app.controller;
import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.stp.StpUtil;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.ResultBean;
import com.seer.teach.common.annotation.DecryptionAnnotation;
import com.seer.teach.common.annotation.EncryptionAnnotation;
import com.seer.teach.common.annotation.LogPrint;
import com.seer.teach.mp.app.controller.req.ActivityFormSubmitReq;
import com.seer.teach.mp.app.controller.req.AppActivityFormExecutionQueryReq;
import com.seer.teach.mp.app.controller.resp.AppActivityFormExecutionResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormFieldResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormTemplateResp;
import com.seer.teach.mp.app.service.IAppActivityFormService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* <p>
* APP端活动表单控制器
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Tag(name = "APP - 活动表单")
@RestController
@RequestMapping("/app/activity/form")
@LogPrint
@EncryptionAnnotation
@DecryptionAnnotation
@RequiredArgsConstructor
@Slf4j
public class AppActivityFormController {
private final IAppActivityFormService appActivityFormService;
@Operation(summary = "获取活动可用的表单")
@GetMapping("/template/{activityId}")
@SaCheckLogin
public ResultBean<AppActivityFormTemplateResp> getTemplateByActivity(@PathVariable Integer activityId) {
AppActivityFormTemplateResp result = appActivityFormService.getTemplateByActivity(activityId);
return ResultBean.success(result);
}
@Operation(summary = "获取表单字段列表")
@GetMapping("/field/{templateId}")
@SaCheckLogin
public ResultBean<List<AppActivityFormFieldResp>> getFieldList(@PathVariable Integer templateId) {
List<AppActivityFormFieldResp> result = appActivityFormService.getFieldListByTemplate(templateId);
return ResultBean.success(result);
}
@Operation(summary = "获取用户提交的表单列表")
@PostMapping("/execution/page-list")
@SaCheckLogin
public ResultBean<PageListBean<AppActivityFormExecutionResp>> getExecutionList(@RequestBody @Valid AppActivityFormExecutionQueryReq query) {
Integer userId = StpUtil.getLoginIdAsInt();
PageListBean<AppActivityFormExecutionResp> result = appActivityFormService.getExecutionList(query, userId);
return ResultBean.success(result);
}
@Operation(summary = "提交表单")
@PostMapping("/submit")
@SaCheckLogin
public ResultBean<String> submitForm(@RequestBody @Valid ActivityFormSubmitReq req) {
Integer userId = StpUtil.getLoginIdAsInt();
String executionNo = appActivityFormService.submitForm(req, userId);
return ResultBean.success(executionNo);
}
@Operation(summary = "获取表单执行详情")
@GetMapping("/execution/{id}")
@SaCheckLogin
public ResultBean<AppActivityFormExecutionResp> getExecutionDetail(@PathVariable Integer id) {
return ResultBean.success(appActivityFormService.getExecutionWithFormData(id));
}
}

View File

@ -0,0 +1,28 @@
package com.seer.teach.mp.app.controller.req;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import jakarta.validation.constraints.NotNull;
import java.util.Map;
@Data
@Schema(description = "活动表单提交请求")
public class ActivityFormSubmitReq {
@Schema(description = "活动ID")
@NotNull(message = "活动ID不能为空")
private Integer activityId;
@Schema(description = "代理商ID")
@NotNull(message = "代理商ID不能为空")
private Integer agentId;
@Schema(description = "表单ID")
@NotNull(message = "表单ID不能为空")
private Integer formId;
@Schema(description = "表单数据")
private Map<String, Object> formData;
}

View File

@ -0,0 +1,19 @@
package com.seer.teach.mp.app.controller.req;
import com.seer.teach.common.request.PageRequest;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "APP端活动表单执行实例查询请求")
public class AppActivityFormExecutionQueryReq extends PageRequest {
@Schema(description = "活动ID")
private Integer activityId;
@Schema(description = "代理商ID")
private Integer agentId;
}

View File

@ -0,0 +1,47 @@
package com.seer.teach.mp.app.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.Map;
@Schema(name = "AppActivityFormExecutionResp", description = "APP端活动表单执行实例响应参数")
@Data
public class AppActivityFormExecutionResp {
private Integer id;
@Schema(description = "执行编号")
private String executionNo;
@Schema(description = "活动ID")
private Integer activityId;
@Schema(description = "代理商ID")
private Integer agentId;
@Schema(description = "使用的表单模板ID")
private Integer templateId;
@Schema(description = "提交人ID")
private Integer submitterId;
@Schema(description = "提交人姓名")
private String submitterName;
@Schema(description = "提交时间")
private LocalDateTime submitTime;
@Schema(description = "状态draft-草稿submitted-已提交approved-已批准rejected-已拒绝")
private String status;
@Schema(description = "表单数据")
private Map<String, Object> formData;
@Schema(description = "创建时间")
private LocalDateTime createTime;
@Schema(description = "更新时间")
private LocalDateTime updateTime;
}

View File

@ -0,0 +1,39 @@
package com.seer.teach.mp.app.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
@Schema(name = "AppActivityFormFieldResp", description = "APP端活动表单字段响应参数")
@Data
public class AppActivityFormFieldResp {
private Integer id;
@Schema(description = "字段名称")
private String fieldName;
@Schema(description = "字段代码(英文标识)")
private String fieldCode;
@Schema(description = "字段类型text, textarea, select, radio, checkbox, date, number等")
private String fieldType;
@Schema(description = "字段选项JSON格式适用于select, radio, checkbox等")
private String fieldOptions;
@Schema(description = "占位符提示")
private String placeholder;
@Schema(description = "是否必填0-否1-是")
private Integer isRequired;
@Schema(description = "排序")
private Integer sortOrder;
@Schema(description = "验证规则JSON格式")
private String validationRules;
@Schema(description = "字段描述")
private String description;
}

View File

@ -0,0 +1,23 @@
package com.seer.teach.mp.app.controller.resp;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import java.util.List;
@Schema(name = "AppActivityFormTemplateResp", description = "APP端活动表单模板响应参数")
@Data
public class AppActivityFormTemplateResp {
private Integer id;
@Schema(description = "表单模板名称")
private String templateName;
@Schema(description = "表单模板描述")
private String templateDescription;
@Schema(description = "表单字段列表")
private List<AppActivityFormFieldResp> fields;
}

View File

@ -0,0 +1,22 @@
package com.seer.teach.mp.app.convert;
import com.seer.teach.mp.app.controller.resp.AppActivityFormExecutionResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormFieldResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormTemplateResp;
import com.seer.teach.mp.entity.MpActivityFormExecutionEntity;
import com.seer.teach.mp.entity.MpActivityFormFieldEntity;
import com.seer.teach.mp.entity.MpActivityFormEntity;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface AppActivityFormConvert {
AppActivityFormConvert INSTANCE = Mappers.getMapper(AppActivityFormConvert.class);
AppActivityFormTemplateResp convertToAppTemplateResp(MpActivityFormEntity entity);
AppActivityFormFieldResp convertToAppFieldResp(MpActivityFormFieldEntity entity);
AppActivityFormExecutionResp convertToAppExecutionResp(MpActivityFormExecutionEntity entity);
}

View File

@ -0,0 +1,63 @@
package com.seer.teach.mp.app.service;
import com.seer.teach.common.PageListBean;
import com.seer.teach.mp.app.controller.req.ActivityFormSubmitReq;
import com.seer.teach.mp.app.controller.req.AppActivityFormExecutionQueryReq;
import com.seer.teach.mp.app.controller.resp.AppActivityFormExecutionResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormTemplateResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormFieldResp;
import java.util.List;
/**
* <p>
* APP端活动表单服务接口
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IAppActivityFormService {
/**
* 根据活动ID获取表单模板
*
* @param activityId 活动ID
* @return 表单模板响应对象
*/
AppActivityFormTemplateResp getTemplateByActivity(Integer activityId);
/**
* 根据模板ID获取字段列表
*
* @param templateId 模板ID
* @return 字段列表
*/
List<AppActivityFormFieldResp> getFieldListByTemplate(Integer templateId);
/**
* 提交表单
*
* @param req 表单提交请求
* @param userId 用户ID
* @return 执行编号
*/
String submitForm(ActivityFormSubmitReq req, Integer userId);
/**
* 根据执行ID获取完整表单数据
*
* @param executionId 执行ID
* @return 完整表单数据
*/
AppActivityFormExecutionResp getExecutionWithFormData(Integer executionId);
/**
* 根据查询条件获取执行列表
*
* @param query 查询条件
* @param userId 用户ID
* @return 执行记录分页列表
*/
PageListBean<AppActivityFormExecutionResp> getExecutionList(AppActivityFormExecutionQueryReq query, Integer userId);
}

View File

@ -0,0 +1,254 @@
package com.seer.teach.mp.app.service.impl;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.seer.teach.common.PageListBean;
import com.seer.teach.common.utils.PageConverterUtils;
import com.seer.teach.mp.app.controller.req.ActivityFormSubmitReq;
import com.seer.teach.mp.app.controller.req.AppActivityFormExecutionQueryReq;
import com.seer.teach.mp.app.controller.resp.AppActivityFormExecutionResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormTemplateResp;
import com.seer.teach.mp.app.controller.resp.AppActivityFormFieldResp;
import com.seer.teach.mp.app.convert.AppActivityFormConvert;
import com.seer.teach.mp.app.service.IAppActivityFormService;
import com.seer.teach.mp.entity.*;
import com.seer.teach.mp.service.*;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* <p>
* APP端活动表单服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class AppActivityFormServiceImpl implements IAppActivityFormService {
private final IMpActivityFormService activityFormTemplateService;
private final IMpActivityFormFieldService activityFormFieldService;
private final IMpActivityFormExecutionService activityFormExecutionService;
private final IMpActivityFormVariableService activityFormVariableService;
private final IMpActivityService mpActivityService;
private final IMpActivityFormRelationService activityFormTemplateRelationService;
@Override
public AppActivityFormTemplateResp getTemplateByActivity(Integer activityId) {
// 首先检查活动是否存在
MpActivityEntity activity = mpActivityService.getById(activityId);
if (activity == null) {
log.warn("活动不存在ID{}", activityId);
return null;
}
// 从关联表中获取与活动关联的表单ID
Integer templateId = activityFormTemplateRelationService.getPrimaryTemplateIdByActivityId(activityId);
if (templateId != null) {
MpActivityFormEntity template = activityFormTemplateService.getById(templateId);
if (template != null) {
AppActivityFormTemplateResp resp = AppActivityFormConvert.INSTANCE.convertToAppTemplateResp(template);
// 获取该表单的所有字段
List<MpActivityFormFieldEntity> fields = activityFormFieldService.list(
new LambdaQueryWrapper<MpActivityFormFieldEntity>()
.eq(MpActivityFormFieldEntity::getFormId, templateId)
.orderByAsc(MpActivityFormFieldEntity::getSortOrder)
.orderByDesc(MpActivityFormFieldEntity::getId)
);
List<AppActivityFormFieldResp> fieldResps = fields.stream()
.map(AppActivityFormConvert.INSTANCE::convertToAppFieldResp)
.collect(Collectors.toList());
resp.setFields(fieldResps);
return resp;
}
}
List<MpActivityFormRelationEntity> relations = activityFormTemplateRelationService.list(
new LambdaQueryWrapper<MpActivityFormRelationEntity>()
.eq(MpActivityFormRelationEntity::getActivityId, activityId)
.last("LIMIT 1")
);
if (!relations.isEmpty()) {
templateId = relations.get(0).getFormId();
MpActivityFormEntity template = activityFormTemplateService.getById(templateId);
if (template != null) {
AppActivityFormTemplateResp resp = AppActivityFormConvert.INSTANCE.convertToAppTemplateResp(template);
// 获取该表单的所有字段
List<MpActivityFormFieldEntity> fields = activityFormFieldService.list(
new LambdaQueryWrapper<MpActivityFormFieldEntity>()
.eq(MpActivityFormFieldEntity::getFormId, templateId)
.orderByAsc(MpActivityFormFieldEntity::getSortOrder)
.orderByDesc(MpActivityFormFieldEntity::getId)
);
List<AppActivityFormFieldResp> fieldResps = fields.stream()
.map(AppActivityFormConvert.INSTANCE::convertToAppFieldResp)
.collect(Collectors.toList());
resp.setFields(fieldResps);
return resp;
}
}
log.warn("未找到活动 {} 关联的表单表单", activityId);
return null;
}
@Override
public List<AppActivityFormFieldResp> getFieldListByTemplate(Integer templateId) {
List<MpActivityFormFieldEntity> fields = activityFormFieldService.list(
new LambdaQueryWrapper<MpActivityFormFieldEntity>()
.eq(MpActivityFormFieldEntity::getFormId, templateId)
.orderByAsc(MpActivityFormFieldEntity::getSortOrder)
.orderByDesc(MpActivityFormFieldEntity::getId)
);
return fields.stream()
.map(AppActivityFormConvert.INSTANCE::convertToAppFieldResp)
.collect(Collectors.toList());
}
@Override
@Transactional
public String submitForm(ActivityFormSubmitReq req, Integer userId) {
// 生成执行编号
String executionNo = "AFE-" + System.currentTimeMillis() + "-" + IdUtil.getSnowflakeNextId();
// 创建表单执行实例
MpActivityFormExecutionEntity execution = new MpActivityFormExecutionEntity();
execution.setExecutionNo(executionNo);
execution.setActivityId(req.getActivityId());
execution.setAgentId(req.getAgentId());
execution.setFormId(req.getFormId());
execution.setSubmitterId(userId); // 设置提交人ID为当前登录用户ID
execution.setSubmitTime(LocalDateTime.now());
execution.setStatus("submitted"); // 设置状态为已提交
// 保存表单执行实例
activityFormExecutionService.save(execution);
// 处理表单数据将其存储到变量表中
if (req.getFormData() != null && !req.getFormData().isEmpty()) {
for (Map.Entry<String, Object> entry : req.getFormData().entrySet()) {
MpActivityFormVariableEntity variable = new MpActivityFormVariableEntity();
variable.setExecutionId(execution.getId());
variable.setVariableName(entry.getKey()); // 使用字段代码作为变量名
variable.setVariableCode(entry.getKey()); // 使用字段代码作为变量代码
variable.setVariableValue(String.valueOf(entry.getValue())); // 将值转换为字符串存储
variable.setDataType(getDataType(entry.getValue())); // 根据值确定数据类型
activityFormVariableService.save(variable);
}
}
log.info("表单提交成功,执行编号:{}", executionNo);
return executionNo;
}
/**
* 根据执行ID获取完整表单数据
*/
public AppActivityFormExecutionResp getExecutionWithFormData(Integer executionId) {
MpActivityFormExecutionEntity execution = activityFormExecutionService.getById(executionId);
if (execution == null) {
return null;
}
AppActivityFormExecutionResp resp = AppActivityFormConvert.INSTANCE.convertToAppExecutionResp(execution);
// 获取表单变量数据
List<MpActivityFormVariableEntity> variables = activityFormVariableService.list(
new LambdaQueryWrapper<MpActivityFormVariableEntity>()
.eq(MpActivityFormVariableEntity::getExecutionId, executionId)
);
// 转换为Map形式的表单数据
Map<String, Object> formData = new HashMap<>();
for (MpActivityFormVariableEntity variable : variables) {
// 根据数据类型转换值
Object value = convertValueByType(variable.getVariableValue(), variable.getDataType());
formData.put(variable.getVariableCode(), value);
}
resp.setFormData(formData);
return resp;
}
/**
* 根据数据类型转换值
*/
private Object convertValueByType(String value, String dataType) {
if (value == null) {
return null;
}
switch (dataType) {
case "boolean":
return Boolean.parseBoolean(value);
case "number":
try {
// 尝试解析为整数或浮点数
if (value.contains(".")) {
return Double.parseDouble(value);
} else {
return Long.parseLong(value);
}
} catch (NumberFormatException e) {
return value; // 如果无法解析为数字则返回原始字符串
}
case "string":
default:
return value;
}
}
/**
* 根据值判断数据类型
*/
private String getDataType(Object value) {
if (value instanceof Boolean) {
return "boolean";
} else if (value instanceof Number) {
return "number";
} else if (value instanceof String) {
return "string";
} else {
return "string";
}
}
@Override
public PageListBean<AppActivityFormExecutionResp> getExecutionList(AppActivityFormExecutionQueryReq query, Integer userId) {
Page<MpActivityFormExecutionEntity> page = new Page<>(query.getPageNo(), query.getPageSize());
LambdaQueryWrapper<MpActivityFormExecutionEntity> wrapper = new LambdaQueryWrapper<>();
wrapper.eq(MpActivityFormExecutionEntity::getSubmitterId, userId)
.eq(query.getActivityId() != null, MpActivityFormExecutionEntity::getActivityId, query.getActivityId())
.eq(query.getAgentId() != null, MpActivityFormExecutionEntity::getAgentId, query.getAgentId())
.orderByDesc(MpActivityFormExecutionEntity::getId);
Page<MpActivityFormExecutionEntity> pageResult = activityFormExecutionService.page(page, wrapper);
List<AppActivityFormExecutionResp> records = pageResult.getRecords().stream()
.map(AppActivityFormConvert.INSTANCE::convertToAppExecutionResp)
.collect(Collectors.toList());
return PageConverterUtils.convertPageListBean(pageResult, records);
}
}

View File

@ -17,9 +17,7 @@ import com.seer.teach.mp.app.service.IAppAgentEmployeeRelationService;
import com.seer.teach.mp.entity.MpAgentEmployeeRelationEntity;
import com.seer.teach.mp.service.IMpAgentEmployeeRelationService;
import com.seer.teach.user.api.UserInfoServiceApi;
import com.seer.teach.user.api.UserRelationServiceApi;
import com.seer.teach.user.api.dto.UserInfoDTO;
import com.seer.teach.user.api.dto.UserRelationDTO;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

View File

@ -0,0 +1,16 @@
package com.seer.teach.mp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.seer.teach.mp.entity.MpActivityFormExecutionEntity;
/**
* <p>
* 活动表单执行实例表 服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IMpActivityFormExecutionService extends IService<MpActivityFormExecutionEntity> {
}

View File

@ -0,0 +1,16 @@
package com.seer.teach.mp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.seer.teach.mp.entity.MpActivityFormFieldEntity;
/**
* <p>
* 活动表单字段定义表 服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IMpActivityFormFieldService extends IService<MpActivityFormFieldEntity> {
}

View File

@ -0,0 +1,50 @@
package com.seer.teach.mp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.seer.teach.mp.entity.MpActivityFormRelationEntity;
import java.util.Optional;
/**
* <p>
* 活动与表单模板关联表 服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IMpActivityFormRelationService extends IService<MpActivityFormRelationEntity> {
/**
* 根据活动ID获取关联的主要表单模板ID
*
* @param activityId 活动ID
* @return 表单模板ID如果不存在则返回null
*/
Integer getPrimaryTemplateIdByActivityId(Integer activityId);
/**
* 根据活动ID获取关联的表单模板数量
*
* @param activityId 活动ID
* @return 表单模板数量
*/
long getCountByActivityId(Integer activityId);
/**
* 根据活动ID和模板ID建立关联
*
* @param activityId 活动ID
* @param formId 表单ID
* @return 操作是否成功
*/
boolean createRelation(Integer activityId, Integer formId);
/**
* 获取指定活动ID的最新版本
*
* @param activityId 活动ID
* @return 最新版本号
*/
Optional<MpActivityFormRelationEntity> getLatestVersionByActivityId(Integer activityId);
}

View File

@ -0,0 +1,16 @@
package com.seer.teach.mp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.seer.teach.mp.entity.MpActivityFormEntity;
/**
* <p>
* 活动表单模板表 服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IMpActivityFormService extends IService<MpActivityFormEntity> {
}

View File

@ -0,0 +1,16 @@
package com.seer.teach.mp.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.seer.teach.mp.entity.MpActivityFormVariableEntity;
/**
* <p>
* 活动表单变量表 服务类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
public interface IMpActivityFormVariableService extends IService<MpActivityFormVariableEntity> {
}

View File

@ -0,0 +1,24 @@
package com.seer.teach.mp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.mp.entity.MpActivityFormExecutionEntity;
import com.seer.teach.mp.mapper.MpActivityFormExecutionMapper;
import com.seer.teach.mp.service.IMpActivityFormExecutionService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* <p>
* 活动表单执行实例表 服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MpActivityFormExecutionServiceImpl extends ServiceImpl<MpActivityFormExecutionMapper, MpActivityFormExecutionEntity> implements IMpActivityFormExecutionService {
}

View File

@ -0,0 +1,24 @@
package com.seer.teach.mp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.mp.entity.MpActivityFormFieldEntity;
import com.seer.teach.mp.mapper.MpActivityFormFieldMapper;
import com.seer.teach.mp.service.IMpActivityFormFieldService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* <p>
* 活动表单字段定义表 服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MpActivityFormFieldServiceImpl extends ServiceImpl<MpActivityFormFieldMapper, MpActivityFormFieldEntity> implements IMpActivityFormFieldService {
}

View File

@ -0,0 +1,73 @@
package com.seer.teach.mp.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.mp.entity.MpActivityFormRelationEntity;
import com.seer.teach.mp.mapper.MpActivityFormRelationMapper;
import com.seer.teach.mp.service.IMpActivityFormRelationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import java.util.Optional;
/**
* <p>
* 活动与表单模板关联表 服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MpActivityFormRelationServiceImpl extends ServiceImpl<MpActivityFormRelationMapper, MpActivityFormRelationEntity> implements IMpActivityFormRelationService {
@Override
public Integer getPrimaryTemplateIdByActivityId(Integer activityId) {
MpActivityFormRelationEntity relation = this.getOne(
new LambdaQueryWrapper<MpActivityFormRelationEntity>()
.eq(MpActivityFormRelationEntity::getActivityId, activityId)
);
return relation != null ? relation.getFormId() : null;
}
@Override
public long getCountByActivityId(Integer activityId) {
return super.count(new LambdaQueryWrapper<MpActivityFormRelationEntity>().eq(MpActivityFormRelationEntity::getActivityId, activityId));
}
@Override
public boolean createRelation(Integer activityId, Integer formId) {
// 检查是否已经存在关联
MpActivityFormRelationEntity existing = this.getOne(
new LambdaQueryWrapper<MpActivityFormRelationEntity>()
.eq(MpActivityFormRelationEntity::getActivityId, activityId)
.eq(MpActivityFormRelationEntity::getFormId, formId)
);
if (existing != null) {
return this.updateById(existing);
} else {
// 创建新的关联
MpActivityFormRelationEntity relation = new MpActivityFormRelationEntity();
relation.setActivityId(activityId);
relation.setFormId(formId);
return this.save(relation);
}
}
@Override
public Optional<MpActivityFormRelationEntity> getLatestVersionByActivityId(Integer activityId) {
MpActivityFormRelationEntity relation = this.getOne(
new LambdaQueryWrapper<MpActivityFormRelationEntity>()
.eq(MpActivityFormRelationEntity::getActivityId, activityId)
.orderByDesc(MpActivityFormRelationEntity::getId)
.last("LIMIT 1")
);
log.info("getLatestVersionByActivityId: {}", relation);
return Optional.ofNullable(relation);
}
}

View File

@ -0,0 +1,24 @@
package com.seer.teach.mp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.mp.entity.MpActivityFormEntity;
import com.seer.teach.mp.mapper.MpActivityFormMapper;
import com.seer.teach.mp.service.IMpActivityFormService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* <p>
* 活动表单模板表 服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MpActivityFormServiceImpl extends ServiceImpl<MpActivityFormMapper, MpActivityFormEntity> implements IMpActivityFormService {
}

View File

@ -0,0 +1,24 @@
package com.seer.teach.mp.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.seer.teach.mp.entity.MpActivityFormVariableEntity;
import com.seer.teach.mp.mapper.MpActivityFormVariableMapper;
import com.seer.teach.mp.service.IMpActivityFormVariableService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
/**
* <p>
* 活动表单变量表 服务实现类
* </p>
*
* @author Lingma
* @since 2026-01-10
*/
@Slf4j
@Service
@RequiredArgsConstructor
public class MpActivityFormVariableServiceImpl extends ServiceImpl<MpActivityFormVariableMapper, MpActivityFormVariableEntity> implements IMpActivityFormVariableService {
}