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