feat(questionnaire): 新增问卷管理 V2 版本接口

- 添加了新的 QuestionnaireV2Controller 类,实现了问卷管理的 CRUD操作
- 新增了问卷答案查看和统计功能相关接口
- 重构了 ResponseDetailResponse 类,将 AnswerDetailResponse 类独立出来- 简化了 CreateQuestionOptionRequest 类的结构
This commit is contained in:
2025-09-06 01:09:17 +08:00
parent 180f89042c
commit 32f7660dc0
4 changed files with 284 additions and 22 deletions

View File

@@ -0,0 +1,264 @@
package com.ycwl.basic.controller.pc;
import com.ycwl.basic.integration.questionnaire.dto.answer.ResponseDetailResponse;
import com.ycwl.basic.integration.questionnaire.dto.questionnaire.CreateQuestionnaireRequest;
import com.ycwl.basic.integration.questionnaire.dto.questionnaire.QuestionnaireResponse;
import com.ycwl.basic.integration.questionnaire.dto.statistics.QuestionnaireStatistics;
import com.ycwl.basic.integration.questionnaire.service.QuestionnaireIntegrationService;
import com.ycwl.basic.integration.common.response.PageResponse;
import com.ycwl.basic.utils.ApiResponse;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
/**
* 问卷管理 V2 版本控制器 - 基于 zt-questionnaire 集成服务
*
* @author Claude Code
* @date 2025-09-05
*/
@Slf4j
@RestController
@RequestMapping("/api/questionnaire/v2")
@RequiredArgsConstructor
public class QuestionnaireV2Controller {
private final QuestionnaireIntegrationService questionnaireIntegrationService;
// ========== 问卷管理 CRUD 操作 ==========
/**
* 分页查询问卷列表
*/
@GetMapping("/")
public ApiResponse<PageResponse<QuestionnaireResponse>> listQuestionnaires(
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) Integer status,
@RequestParam(required = false) String name) {
log.info("分页查询问卷列表, page: {}, pageSize: {}, status: {}, name: {}",
page, pageSize, status, name);
// 参数验证:限制pageSize最大值为100
if (pageSize > 100) {
pageSize = 100;
}
try {
PageResponse<QuestionnaireResponse> response =
questionnaireIntegrationService.getQuestionnaireList(page, pageSize, name, status, null);
return ApiResponse.success(response);
} catch (Exception e) {
log.error("分页查询问卷列表失败", e);
return ApiResponse.fail("分页查询问卷列表失败: " + e.getMessage());
}
}
/**
* 获取问卷详情
*/
@GetMapping("/{id}")
public ApiResponse<QuestionnaireResponse> getQuestionnaire(@PathVariable Long id) {
log.info("获取问卷详情, id: {}", id);
try {
QuestionnaireResponse questionnaire = questionnaireIntegrationService.getQuestionnaire(id);
return ApiResponse.success(questionnaire);
} catch (Exception e) {
log.error("获取问卷详情失败, id: {}", id, e);
return ApiResponse.fail("获取问卷详情失败: " + e.getMessage());
}
}
/**
* 创建问卷
*/
@PostMapping("/")
public ApiResponse<QuestionnaireResponse> createQuestionnaire(@Valid @RequestBody CreateQuestionnaireRequest request) {
log.info("创建问卷, name: {}, questions count: {}",
request.getName(), request.getQuestions() != null ? request.getQuestions().size() : 0);
try {
QuestionnaireResponse questionnaire = questionnaireIntegrationService.createQuestionnaire(request, "admin");
return ApiResponse.success(questionnaire);
} catch (Exception e) {
log.error("创建问卷失败", e);
return ApiResponse.fail("创建问卷失败: " + e.getMessage());
}
}
/**
* 更新问卷
*/
@PutMapping("/{id}")
public ApiResponse<QuestionnaireResponse> updateQuestionnaire(
@PathVariable Long id,
@Valid @RequestBody CreateQuestionnaireRequest request) {
log.info("更新问卷, id: {}", id);
try {
QuestionnaireResponse questionnaire = questionnaireIntegrationService.updateQuestionnaire(id, request, "admin");
return ApiResponse.success(questionnaire);
} catch (Exception e) {
log.error("更新问卷失败, id: {}", id, e);
return ApiResponse.fail("更新问卷失败: " + e.getMessage());
}
}
/**
* 更新问卷状态
*/
@PutMapping("/{id}/status")
public ApiResponse<String> updateQuestionnaireStatus(@PathVariable Long id, @RequestBody Map<String, Integer> request) {
Integer status = request.get("status");
log.info("更新问卷状态, id: {}, status: {}", id, status);
try {
// 根据状态调用不同的方法
if (status == 2) {
questionnaireIntegrationService.publishQuestionnaire(id, "admin");
} else if (status == 3) {
questionnaireIntegrationService.stopQuestionnaire(id, "admin");
}
return ApiResponse.success("问卷状态更新成功");
} catch (Exception e) {
log.error("更新问卷状态失败, id: {}, status: {}", id, status, e);
return ApiResponse.fail("更新问卷状态失败: " + e.getMessage());
}
}
/**
* 发布问卷
*/
@PutMapping("/{id}/publish")
public ApiResponse<String> publishQuestionnaire(@PathVariable Long id) {
log.info("发布问卷, id: {}", id);
try {
questionnaireIntegrationService.publishQuestionnaire(id, "admin");
return ApiResponse.success("问卷发布成功");
} catch (Exception e) {
log.error("发布问卷失败, id: {}", id, e);
return ApiResponse.fail("发布问卷失败: " + e.getMessage());
}
}
/**
* 停止问卷
*/
@PutMapping("/{id}/stop")
public ApiResponse<String> stopQuestionnaire(@PathVariable Long id) {
log.info("停止问卷, id: {}", id);
try {
questionnaireIntegrationService.stopQuestionnaire(id, "admin");
return ApiResponse.success("问卷停止成功");
} catch (Exception e) {
log.error("停止问卷失败, id: {}", id, e);
return ApiResponse.fail("停止问卷失败: " + e.getMessage());
}
}
/**
* 删除问卷
*/
@DeleteMapping("/{id}")
public ApiResponse<String> deleteQuestionnaire(@PathVariable Long id) {
log.info("删除问卷, id: {}", id);
try {
questionnaireIntegrationService.deleteQuestionnaire(id, "admin");
return ApiResponse.success("问卷删除成功");
} catch (Exception e) {
log.error("删除问卷失败, id: {}", id, e);
return ApiResponse.fail("删除问卷失败: " + e.getMessage());
}
}
// ========== 问卷答案查看操作 ==========
/**
* 分页查询问卷答案
*/
@GetMapping("/{id}/answers")
public ApiResponse<PageResponse<ResponseDetailResponse>> getQuestionnaireAnswers(
@PathVariable Long id,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) String userId,
@RequestParam(required = false) String startTime,
@RequestParam(required = false) String endTime) {
log.info("分页查询问卷答案, questionnaireId: {}, page: {}, pageSize: {}, userId: {}",
id, page, pageSize, userId);
// 参数验证:限制pageSize最大值为100
if (pageSize > 100) {
pageSize = 100;
}
try {
PageResponse<ResponseDetailResponse> response =
questionnaireIntegrationService.getResponseList(page, pageSize, id, userId, startTime, endTime);
return ApiResponse.success(response);
} catch (Exception e) {
log.error("分页查询问卷答案失败, questionnaireId: {}", id, e);
return ApiResponse.fail("分页查询问卷答案失败: " + e.getMessage());
}
}
/**
* 获取特定答案详情
*/
@GetMapping("/{id}/answers/{answerId}")
public ApiResponse<ResponseDetailResponse> getQuestionnaireAnswer(@PathVariable Long id, @PathVariable Long answerId) {
log.info("获取问卷答案详情, questionnaireId: {}, answerId: {}", id, answerId);
try {
ResponseDetailResponse answer = questionnaireIntegrationService.getResponseDetail(answerId);
return ApiResponse.success(answer);
} catch (Exception e) {
log.error("获取问卷答案详情失败, questionnaireId: {}, answerId: {}", id, answerId, e);
return ApiResponse.fail("获取问卷答案详情失败: " + e.getMessage());
}
}
/**
* 查询用户答题记录
*/
@GetMapping("/answers/user/{userId}")
public ApiResponse<PageResponse<ResponseDetailResponse>> getUserAnswers(
@PathVariable String userId,
@RequestParam(defaultValue = "1") Integer page,
@RequestParam(defaultValue = "10") Integer pageSize,
@RequestParam(required = false) Long questionnaireId) {
log.info("查询用户答题记录, userId: {}, page: {}, pageSize: {}, questionnaireId: {}",
userId, page, pageSize, questionnaireId);
// 参数验证:限制pageSize最大值为100
if (pageSize > 100) {
pageSize = 100;
}
try {
PageResponse<ResponseDetailResponse> response =
questionnaireIntegrationService.getResponseList(page, pageSize, questionnaireId, userId, null, null);
return ApiResponse.success(response);
} catch (Exception e) {
log.error("查询用户答题记录失败, userId: {}", userId, e);
return ApiResponse.fail("查询用户答题记录失败: " + e.getMessage());
}
}
// ========== 统计功能 ==========
/**
* 获取问卷统计信息
*/
@GetMapping("/{id}/statistics")
public ApiResponse<QuestionnaireStatistics> getQuestionnaireStatistics(@PathVariable Long id) {
log.info("获取问卷统计信息, id: {}", id);
try {
QuestionnaireStatistics statistics = questionnaireIntegrationService.getStatistics(id);
return ApiResponse.success(statistics);
} catch (Exception e) {
log.error("获取问卷统计信息失败, id: {}", id, e);
return ApiResponse.fail("获取问卷统计信息失败: " + e.getMessage());
}
}
}

View File

@@ -0,0 +1,20 @@
package com.ycwl.basic.integration.questionnaire.dto.answer;
import com.fasterxml.jackson.annotation.JsonProperty;
import lombok.Data;
@Data
public class AnswerDetailResponse {
@JsonProperty("questionId")
private Long questionId;
@JsonProperty("questionTitle")
private String questionTitle;
@JsonProperty("questionType")
private Integer questionType;
@JsonProperty("answer")
private String answer;
}

View File

@@ -26,19 +26,3 @@ public class ResponseDetailResponse {
@JsonProperty("answers") @JsonProperty("answers")
private List<AnswerDetailResponse> answers; private List<AnswerDetailResponse> answers;
} }
@Data
class AnswerDetailResponse {
@JsonProperty("questionId")
private Long questionId;
@JsonProperty("questionTitle")
private String questionTitle;
@JsonProperty("questionType")
private Integer questionType;
@JsonProperty("answer")
private String answer;
}

View File

@@ -25,10 +25,4 @@ public class CreateQuestionOptionRequest {
@JsonProperty("sort") @JsonProperty("sort")
private Integer sort = 0; private Integer sort = 0;
public CreateQuestionOptionRequest(String text, String value, Integer sort) {
this.text = text;
this.value = value;
this.sort = sort;
}
} }