Archived
init
This commit is contained in:
+33
@@ -0,0 +1,33 @@
|
||||
HELP.MD
|
||||
target/
|
||||
!.mvn/wrapper/maven-wrapper.jar
|
||||
!**/src/main/**/target/
|
||||
!**/src/test/**/target/
|
||||
|
||||
### STS ###
|
||||
.apt_generated
|
||||
.classpath
|
||||
.factorypath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.sts4-cache
|
||||
|
||||
### IntelliJ IDEA ###
|
||||
.idea
|
||||
*.iws
|
||||
*.iml
|
||||
*.ipr
|
||||
|
||||
### NetBeans ###
|
||||
/nbproject/private/
|
||||
/nbbuild/
|
||||
/dist/
|
||||
/nbdist/
|
||||
/.nb-gradle/
|
||||
build/
|
||||
!**/src/main/**/build/
|
||||
!**/src/test/**/build/
|
||||
|
||||
### VS Code ###
|
||||
.vscode/
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
FROM eclipse-temurin:25-jre-alpine
|
||||
|
||||
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
COPY target/gmp-mock-service.jar app.jar
|
||||
|
||||
RUN chown -R appuser:appgroup /app
|
||||
|
||||
USER appuser
|
||||
|
||||
EXPOSE 8080
|
||||
|
||||
ENTRYPOINT ["java", "-jar", "app.jar"]
|
||||
@@ -0,0 +1,15 @@
|
||||
Write-Host "===== 开始构建 gmp-mock-service =====" -ForegroundColor Cyan
|
||||
|
||||
mvn clean package -DskipTests
|
||||
|
||||
if ($LASTEXITCODE -eq 0) {
|
||||
Write-Host "===== 构建成功 =====" -ForegroundColor Green
|
||||
$jarPath = "target\gmp-mock-service.jar"
|
||||
if (Test-Path $jarPath) {
|
||||
$size = [math]::Round((Get-Item $jarPath).Length / 1MB, 2)
|
||||
Write-Host "JAR 文件: $jarPath ($size MB)" -ForegroundColor Green
|
||||
}
|
||||
} else {
|
||||
Write-Host "===== 构建失败 =====" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
echo "===== 开始构建 gmp-mock-service ====="
|
||||
|
||||
mvn clean package -DskipTests
|
||||
|
||||
if [ $? -eq 0 ]; then
|
||||
echo "===== 构建成功 ====="
|
||||
JAR_PATH="target/gmp-mock-service.jar"
|
||||
if [ -f "$JAR_PATH" ]; then
|
||||
SIZE=$(du -h "$JAR_PATH" | cut -f1)
|
||||
echo "JAR 文件: $JAR_PATH ($SIZE)"
|
||||
fi
|
||||
else
|
||||
echo "===== 构建失败 ====="
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,14 @@
|
||||
$jarPath = "target\gmp-mock-service.jar"
|
||||
|
||||
if (-not (Test-Path $jarPath)) {
|
||||
Write-Host "JAR 文件不存在,请先执行 build.ps1 进行构建" -ForegroundColor Red
|
||||
exit 1
|
||||
}
|
||||
|
||||
$env:JAVA_OPTS = $env:JAVA_OPTS ?? "-Xms256m -Xmx512m"
|
||||
|
||||
Write-Host "===== 启动 gmp-mock-service =====" -ForegroundColor Cyan
|
||||
Write-Host "端口: 8080" -ForegroundColor Cyan
|
||||
Write-Host "接口: POST http://localhost:8080/api/docx/export" -ForegroundColor Cyan
|
||||
|
||||
java $env:JAVA_OPTS -jar $jarPath
|
||||
@@ -0,0 +1,16 @@
|
||||
#!/bin/bash
|
||||
|
||||
JAR_PATH="target/gmp-mock-service.jar"
|
||||
|
||||
if [ ! -f "$JAR_PATH" ]; then
|
||||
echo "JAR 文件不存在,请先执行 build.sh 进行构建"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
JAVA_OPTS="${JAVA_OPTS:--Xms256m -Xmx512m}"
|
||||
|
||||
echo "===== 启动 gmp-mock-service ====="
|
||||
echo "端口: 8080"
|
||||
echo "接口: POST http://localhost:8080/api/docx/export"
|
||||
|
||||
java $JAVA_OPTS -jar "$JAR_PATH"
|
||||
@@ -0,0 +1,60 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>3.5.1</version>
|
||||
<relativePath/>
|
||||
</parent>
|
||||
|
||||
<groupId>com.gmp</groupId>
|
||||
<artifactId>gmp-service</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<packaging>jar</packaging>
|
||||
<name>gmp-mock-service</name>
|
||||
<description>GMP Mock Service - 提供简单接口的模拟服务</description>
|
||||
|
||||
<properties>
|
||||
<java.version>25</java.version>
|
||||
<poi.version>5.4.0</poi.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.poi</groupId>
|
||||
<artifactId>poi-ooxml</artifactId>
|
||||
<version>${poi.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<finalName>${project.artifactId}</finalName>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
</project>
|
||||
@@ -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 {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
server:
|
||||
port: 8080
|
||||
|
||||
spring:
|
||||
application:
|
||||
name: gmp-mock-service
|
||||
Reference in New Issue
Block a user