This commit is contained in:
CloseIn
2026-05-07 15:54:19 +08:00
commit ac5a30844e
18 changed files with 461 additions and 0 deletions
@@ -0,0 +1,12 @@
package com.gmp.mock;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MockApplication {
public static void main(String[] args) {
SpringApplication.run(MockApplication.class, args);
}
}
@@ -0,0 +1,36 @@
package com.gmp.mock.controller;
import java.io.IOException;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
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 com.gmp.mock.dto.ApiResponse;
import com.gmp.mock.dto.DocxExportData;
import com.gmp.mock.dto.DocxExportRequest;
import com.gmp.mock.service.DocxService;
@RestController
@RequestMapping("/api/docx")
public class DocxController {
private final DocxService docxService;
public DocxController(DocxService docxService) {
this.docxService = docxService;
}
@PostMapping("/export")
public ResponseEntity<ApiResponse<DocxExportData>> exportDocx(@Valid @RequestBody DocxExportRequest request) throws IOException {
DocxExportData data = docxService.export(request.getExportId());
if (data == null) {
return ResponseEntity.ok(ApiResponse.error(404, "模板不存在"));
}
return ResponseEntity.ok(ApiResponse.success(data));
}
}
@@ -0,0 +1,50 @@
package com.gmp.mock.dto;
public class ApiResponse<T> {
private int code;
private T data;
private String msg;
private ApiResponse(int code, T data, String msg) {
this.code = code;
this.data = data;
this.msg = msg;
}
public static <T> ApiResponse<T> success(T data) {
return new ApiResponse<>(0, data, "success");
}
public static <T> ApiResponse<T> success(T data, String msg) {
return new ApiResponse<>(0, data, msg);
}
public static <T> ApiResponse<T> error(int code, String msg) {
return new ApiResponse<>(code, null, msg);
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
@@ -0,0 +1,28 @@
package com.gmp.mock.dto;
public class DocxExportData {
private String fileName;
private String fileBase64;
public DocxExportData(String fileName, String fileBase64) {
this.fileName = fileName;
this.fileBase64 = fileBase64;
}
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String getFileBase64() {
return fileBase64;
}
public void setFileBase64(String fileBase64) {
this.fileBase64 = fileBase64;
}
}
@@ -0,0 +1,31 @@
package com.gmp.mock.dto;
import java.util.Map;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
public class DocxExportRequest {
@NotBlank(message = "exportId 不能为空")
private String exportId;
@NotNull(message = "businessData 不能为空")
private Map<String, Object> businessData;
public String getExportId() {
return exportId;
}
public void setExportId(String exportId) {
this.exportId = exportId;
}
public Map<String, Object> getBusinessData() {
return businessData;
}
public void setBusinessData(Map<String, Object> businessData) {
this.businessData = businessData;
}
}
@@ -0,0 +1,22 @@
package com.gmp.mock.handler;
import java.util.stream.Collectors;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import com.gmp.mock.dto.ApiResponse;
@RestControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(MethodArgumentNotValidException.class)
public ResponseEntity<ApiResponse<Void>> handleValidation(MethodArgumentNotValidException ex) {
String message = ex.getBindingResult().getFieldErrors().stream()
.map(e -> e.getDefaultMessage())
.collect(Collectors.joining("; "));
return ResponseEntity.ok(ApiResponse.error(400, message));
}
}
@@ -0,0 +1,37 @@
package com.gmp.mock.service;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Base64;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Service;
import com.gmp.mock.dto.DocxExportData;
import com.gmp.mock.template.TemplateProvider;
import com.gmp.mock.template.TemplateRegistry;
@Service
public class DocxService {
private final TemplateRegistry templateRegistry;
public DocxService(TemplateRegistry templateRegistry) {
this.templateRegistry = templateRegistry;
}
public DocxExportData export(String exportId) throws IOException {
TemplateProvider provider = templateRegistry.get(exportId);
if (provider == null) {
return null;
}
try (XWPFDocument document = new XWPFDocument();
ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
provider.generate(document);
document.write(baos);
String base64 = Base64.getEncoder().encodeToString(baos.toByteArray());
return new DocxExportData(provider.getFileName(), base64);
}
}
}
@@ -0,0 +1,14 @@
package com.gmp.mock.template;
import java.io.IOException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
public interface TemplateProvider {
String getTemplateId();
String getFileName();
void generate(XWPFDocument document) throws IOException;
}
@@ -0,0 +1,27 @@
package com.gmp.mock.template;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.springframework.stereotype.Component;
@Component
public class TemplateRegistry {
private final Map<String, TemplateProvider> providers;
public TemplateRegistry(List<TemplateProvider> providers) {
this.providers = providers.stream()
.collect(Collectors.toMap(TemplateProvider::getTemplateId, Function.identity()));
}
public TemplateProvider get(String templateId) {
return providers.get(templateId);
}
public boolean exists(String templateId) {
return providers.containsKey(templateId);
}
}
@@ -0,0 +1,26 @@
package com.gmp.mock.template.annualReport;
import java.io.IOException;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.springframework.stereotype.Component;
import com.gmp.mock.template.TemplateProvider;
@Component
public class AnnualReportProvider implements TemplateProvider {
@Override
public String getTemplateId() {
return "annualReport";
}
@Override
public String getFileName() {
return "annualReport.docx";
}
@Override
public void generate(XWPFDocument document) throws IOException {
}
}
+6
View File
@@ -0,0 +1,6 @@
server:
port: 8080
spring:
application:
name: gmp-mock-service