|
|
@@ -0,0 +1,333 @@
|
|
|
+package com.lingyue.extract.controller;
|
|
|
+
|
|
|
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
|
|
+import com.lingyue.common.domain.AjaxResult;
|
|
|
+import com.lingyue.extract.dto.request.AddSourceFileRequest;
|
|
|
+import com.lingyue.extract.dto.request.AddVariableRequest;
|
|
|
+import com.lingyue.extract.dto.request.CreateTemplateRequest;
|
|
|
+import com.lingyue.extract.dto.request.UpdateTemplateRequest;
|
|
|
+import com.lingyue.extract.dto.response.SourceFileResponse;
|
|
|
+import com.lingyue.extract.dto.response.TemplateDetailResponse;
|
|
|
+import com.lingyue.extract.dto.response.TemplateListResponse;
|
|
|
+import com.lingyue.extract.dto.response.VariableResponse;
|
|
|
+import com.lingyue.extract.entity.SourceFile;
|
|
|
+import com.lingyue.extract.entity.Template;
|
|
|
+import com.lingyue.extract.entity.Variable;
|
|
|
+import com.lingyue.extract.service.SourceFileService;
|
|
|
+import com.lingyue.extract.service.TemplateService;
|
|
|
+import com.lingyue.extract.service.VariableService;
|
|
|
+import io.swagger.v3.oas.annotations.Operation;
|
|
|
+import io.swagger.v3.oas.annotations.Parameter;
|
|
|
+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.*;
|
|
|
+
|
|
|
+import java.util.List;
|
|
|
+import java.util.stream.Collectors;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 模板管理控制器
|
|
|
+ *
|
|
|
+ * @author lingyue
|
|
|
+ * @since 2026-01-23
|
|
|
+ */
|
|
|
+@Slf4j
|
|
|
+@RestController
|
|
|
+@RequestMapping("/api/v1/templates")
|
|
|
+@RequiredArgsConstructor
|
|
|
+@Tag(name = "模板管理", description = "报告模板 CRUD 接口")
|
|
|
+public class TemplateController {
|
|
|
+
|
|
|
+ private final TemplateService templateService;
|
|
|
+ private final SourceFileService sourceFileService;
|
|
|
+ private final VariableService variableService;
|
|
|
+
|
|
|
+ // TODO: 从认证上下文获取用户ID
|
|
|
+ private String getCurrentUserId() {
|
|
|
+ return "test-user-001";
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 模板 CRUD ====================
|
|
|
+
|
|
|
+ @PostMapping
|
|
|
+ @Operation(summary = "创建模板", description = "创建新的报告模板")
|
|
|
+ public AjaxResult<?> createTemplate(@Valid @RequestBody CreateTemplateRequest request) {
|
|
|
+ try {
|
|
|
+ String userId = getCurrentUserId();
|
|
|
+ Template template = templateService.create(userId, request);
|
|
|
+ return AjaxResult.success("创建成功", TemplateDetailResponse.fromEntity(template));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("创建模板失败", e);
|
|
|
+ return AjaxResult.error("创建失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/{id}")
|
|
|
+ @Operation(summary = "获取模板详情", description = "获取模板详情,包含来源文件和变量列表")
|
|
|
+ public AjaxResult<?> getTemplate(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String id) {
|
|
|
+ TemplateDetailResponse response = templateService.getTemplateDetail(id);
|
|
|
+ if (response == null) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success(response);
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping
|
|
|
+ @Operation(summary = "获取模板列表", description = "分页获取当前用户的模板列表")
|
|
|
+ public AjaxResult<?> listTemplates(
|
|
|
+ @Parameter(description = "页码") @RequestParam(defaultValue = "1") int page,
|
|
|
+ @Parameter(description = "每页数量") @RequestParam(defaultValue = "20") int size) {
|
|
|
+ String userId = getCurrentUserId();
|
|
|
+ Page<TemplateListResponse> result = templateService.listByUserId(userId, page, size);
|
|
|
+ return AjaxResult.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/accessible")
|
|
|
+ @Operation(summary = "获取可访问的模板", description = "获取用户可见的模板(自己的 + 公开的)")
|
|
|
+ public AjaxResult<?> listAccessibleTemplates() {
|
|
|
+ String userId = getCurrentUserId();
|
|
|
+ List<TemplateListResponse> result = templateService.listAccessible(userId);
|
|
|
+ return AjaxResult.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/search")
|
|
|
+ @Operation(summary = "搜索模板", description = "按名称搜索模板")
|
|
|
+ public AjaxResult<?> searchTemplates(
|
|
|
+ @Parameter(description = "关键词") @RequestParam String keyword) {
|
|
|
+ String userId = getCurrentUserId();
|
|
|
+ List<TemplateListResponse> result = templateService.search(userId, keyword);
|
|
|
+ return AjaxResult.success(result);
|
|
|
+ }
|
|
|
+
|
|
|
+ @PutMapping("/{id}")
|
|
|
+ @Operation(summary = "更新模板", description = "更新模板基本信息")
|
|
|
+ public AjaxResult<?> updateTemplate(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String id,
|
|
|
+ @Valid @RequestBody UpdateTemplateRequest request) {
|
|
|
+ try {
|
|
|
+ Template template = templateService.update(id, request);
|
|
|
+ if (template == null) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("更新成功", TemplateDetailResponse.fromEntity(template));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新模板失败", e);
|
|
|
+ return AjaxResult.error("更新失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @DeleteMapping("/{id}")
|
|
|
+ @Operation(summary = "删除模板", description = "删除模板(级联删除来源文件和变量)")
|
|
|
+ public AjaxResult<?> deleteTemplate(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String id) {
|
|
|
+ try {
|
|
|
+ boolean success = templateService.delete(id);
|
|
|
+ if (!success) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("删除成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("删除模板失败", e);
|
|
|
+ return AjaxResult.error("删除失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 模板状态操作 ====================
|
|
|
+
|
|
|
+ @PostMapping("/{id}/publish")
|
|
|
+ @Operation(summary = "发布模板", description = "将模板状态改为已发布")
|
|
|
+ public AjaxResult<?> publishTemplate(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String id) {
|
|
|
+ try {
|
|
|
+ Template template = templateService.publish(id);
|
|
|
+ if (template == null) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("发布成功", TemplateDetailResponse.fromEntity(template));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("发布模板失败", e);
|
|
|
+ return AjaxResult.error("发布失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping("/{id}/archive")
|
|
|
+ @Operation(summary = "归档模板", description = "将模板状态改为已归档")
|
|
|
+ public AjaxResult<?> archiveTemplate(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String id) {
|
|
|
+ try {
|
|
|
+ Template template = templateService.archive(id);
|
|
|
+ if (template == null) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("归档成功", TemplateDetailResponse.fromEntity(template));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("归档模板失败", e);
|
|
|
+ return AjaxResult.error("归档失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @PostMapping("/{id}/duplicate")
|
|
|
+ @Operation(summary = "复制模板", description = "复制模板及其来源文件和变量")
|
|
|
+ public AjaxResult<?> duplicateTemplate(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String id,
|
|
|
+ @Parameter(description = "新模板名称") @RequestParam(required = false) String newName) {
|
|
|
+ try {
|
|
|
+ String userId = getCurrentUserId();
|
|
|
+ Template template = templateService.duplicate(id, userId, newName);
|
|
|
+ if (template == null) {
|
|
|
+ return AjaxResult.error("模板不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("复制成功", TemplateDetailResponse.fromEntity(template));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("复制模板失败", e);
|
|
|
+ return AjaxResult.error("复制失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 来源文件管理 ====================
|
|
|
+
|
|
|
+ @PostMapping("/{templateId}/source-files")
|
|
|
+ @Operation(summary = "添加来源文件定义", description = "为模板添加来源文件定义")
|
|
|
+ public AjaxResult<?> addSourceFile(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String templateId,
|
|
|
+ @Valid @RequestBody AddSourceFileRequest request) {
|
|
|
+ try {
|
|
|
+ SourceFile sourceFile = sourceFileService.add(templateId, request);
|
|
|
+ return AjaxResult.success("添加成功", SourceFileResponse.fromEntity(sourceFile));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("添加来源文件定义失败", e);
|
|
|
+ return AjaxResult.error("添加失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/{templateId}/source-files")
|
|
|
+ @Operation(summary = "获取来源文件定义列表", description = "获取模板的所有来源文件定义")
|
|
|
+ public AjaxResult<?> listSourceFiles(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String templateId) {
|
|
|
+ List<SourceFile> sourceFiles = sourceFileService.listByTemplateId(templateId);
|
|
|
+ List<SourceFileResponse> responses = sourceFiles.stream()
|
|
|
+ .map(SourceFileResponse::fromEntity)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ return AjaxResult.success(responses);
|
|
|
+ }
|
|
|
+
|
|
|
+ @PutMapping("/source-files/{id}")
|
|
|
+ @Operation(summary = "更新来源文件定义", description = "更新来源文件定义")
|
|
|
+ public AjaxResult<?> updateSourceFile(
|
|
|
+ @Parameter(description = "来源文件定义ID") @PathVariable String id,
|
|
|
+ @Valid @RequestBody AddSourceFileRequest request) {
|
|
|
+ try {
|
|
|
+ SourceFile sourceFile = sourceFileService.update(id, request);
|
|
|
+ if (sourceFile == null) {
|
|
|
+ return AjaxResult.error("来源文件定义不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("更新成功", SourceFileResponse.fromEntity(sourceFile));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新来源文件定义失败", e);
|
|
|
+ return AjaxResult.error("更新失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @DeleteMapping("/source-files/{id}")
|
|
|
+ @Operation(summary = "删除来源文件定义", description = "删除来源文件定义")
|
|
|
+ public AjaxResult<?> deleteSourceFile(
|
|
|
+ @Parameter(description = "来源文件定义ID") @PathVariable String id,
|
|
|
+ @Parameter(description = "是否强制删除") @RequestParam(defaultValue = "false") boolean force) {
|
|
|
+ try {
|
|
|
+ boolean success = force ? sourceFileService.forceDelete(id) : sourceFileService.delete(id);
|
|
|
+ if (!success) {
|
|
|
+ return AjaxResult.error("来源文件定义不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("删除成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("删除来源文件定义失败", e);
|
|
|
+ return AjaxResult.error("删除失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // ==================== 变量管理 ====================
|
|
|
+
|
|
|
+ @PostMapping("/{templateId}/variables")
|
|
|
+ @Operation(summary = "添加变量", description = "为模板添加变量")
|
|
|
+ public AjaxResult<?> addVariable(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String templateId,
|
|
|
+ @Valid @RequestBody AddVariableRequest request) {
|
|
|
+ try {
|
|
|
+ Variable variable = variableService.add(templateId, request);
|
|
|
+ return AjaxResult.success("添加成功", VariableResponse.fromEntity(variable));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("添加变量失败", e);
|
|
|
+ return AjaxResult.error("添加失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/{templateId}/variables")
|
|
|
+ @Operation(summary = "获取变量列表", description = "获取模板的所有变量")
|
|
|
+ public AjaxResult<?> listVariables(
|
|
|
+ @Parameter(description = "模板ID") @PathVariable String templateId,
|
|
|
+ @Parameter(description = "来源文件别名过滤") @RequestParam(required = false) String sourceFileAlias,
|
|
|
+ @Parameter(description = "变量分组过滤") @RequestParam(required = false) String group) {
|
|
|
+ List<Variable> variables;
|
|
|
+
|
|
|
+ if (sourceFileAlias != null) {
|
|
|
+ variables = variableService.listBySourceFileAlias(templateId, sourceFileAlias);
|
|
|
+ } else if (group != null) {
|
|
|
+ variables = variableService.listByGroup(templateId, group);
|
|
|
+ } else {
|
|
|
+ variables = variableService.listByTemplateId(templateId);
|
|
|
+ }
|
|
|
+
|
|
|
+ List<VariableResponse> responses = variables.stream()
|
|
|
+ .map(VariableResponse::fromEntity)
|
|
|
+ .collect(Collectors.toList());
|
|
|
+ return AjaxResult.success(responses);
|
|
|
+ }
|
|
|
+
|
|
|
+ @GetMapping("/variables/{id}")
|
|
|
+ @Operation(summary = "获取变量详情", description = "获取变量详情")
|
|
|
+ public AjaxResult<?> getVariable(
|
|
|
+ @Parameter(description = "变量ID") @PathVariable String id) {
|
|
|
+ Variable variable = variableService.getById(id);
|
|
|
+ if (variable == null) {
|
|
|
+ return AjaxResult.error("变量不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success(VariableResponse.fromEntity(variable));
|
|
|
+ }
|
|
|
+
|
|
|
+ @PutMapping("/variables/{id}")
|
|
|
+ @Operation(summary = "更新变量", description = "更新变量")
|
|
|
+ public AjaxResult<?> updateVariable(
|
|
|
+ @Parameter(description = "变量ID") @PathVariable String id,
|
|
|
+ @Valid @RequestBody AddVariableRequest request) {
|
|
|
+ try {
|
|
|
+ Variable variable = variableService.update(id, request);
|
|
|
+ if (variable == null) {
|
|
|
+ return AjaxResult.error("变量不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("更新成功", VariableResponse.fromEntity(variable));
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("更新变量失败", e);
|
|
|
+ return AjaxResult.error("更新失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ @DeleteMapping("/variables/{id}")
|
|
|
+ @Operation(summary = "删除变量", description = "删除变量")
|
|
|
+ public AjaxResult<?> deleteVariable(
|
|
|
+ @Parameter(description = "变量ID") @PathVariable String id,
|
|
|
+ @Parameter(description = "是否强制删除") @RequestParam(defaultValue = "false") boolean force) {
|
|
|
+ try {
|
|
|
+ boolean success = force ? variableService.forceDelete(id) : variableService.delete(id);
|
|
|
+ if (!success) {
|
|
|
+ return AjaxResult.error("变量不存在");
|
|
|
+ }
|
|
|
+ return AjaxResult.success("删除成功");
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error("删除变量失败", e);
|
|
|
+ return AjaxResult.error("删除失败: " + e.getMessage());
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|