Skip to content

Commit 937f9f4

Browse files
committed
refactor(generator): 重构代码生成器模板
- 更新 Java 相关模板,增加 SDK、Spring Boot 等模板 - 更新 Node.js 相关模板,调整文件路径生成逻辑 - 删除部分不再使用的模板文件 - 新增 Java SDK 相关的枚举、API 客户端等模板
1 parent a994099 commit 937f9f4

File tree

25 files changed

+482
-39
lines changed

25 files changed

+482
-39
lines changed

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,14 @@
1515
<url>https://maven.pkg.github.com/flexmodel-projects/flexmodel-maven-packages</url>
1616
</repository>
1717
</distributionManagement>
18+
<dependencies>
19+
<dependency>
20+
<groupId>tech.wetech.flexmodel</groupId>
21+
<artifactId>flexmodel-codegen</artifactId>
22+
<version>0.0.1-SNAPSHOT</version>
23+
<optional>true</optional>
24+
</dependency>
25+
</dependencies>
1826

1927
<build>
2028
<resources>

src/main/templates/java_sample/src/main/java/${packageNameAsPath}/entity/PojoGenerator.groovy renamed to src/main/templates/java_sample/src/main/java/${packageNameAsPath}/entity/SamplePojoGenerator.groovy

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import java.nio.file.Path
1010
*
1111
* Author: cjbi
1212
*/
13-
class PojoGenerator extends AbstractGenerator {
13+
class SamplePojoGenerator extends AbstractGenerator {
1414

1515
@Override
1616
String getTargetFile(GenerationContext context, String targetDirectory) {
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import java.nio.file.Path
99
* @author cjbi
1010
*/
1111
@Log
12-
class EnumGenerator extends AbstractGenerator {
12+
class SampleEnumGenerator extends AbstractGenerator {
1313

1414
@Override
1515
String getTargetFile(GenerationContext context, String targetDirectory) {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Flexmodel Java SDK 模板
2+
3+
该模板提供访问 Flexmodel 后端的简易 Java SDK,覆盖模型数据记录 CRUD 接口。
4+
5+
快速开始:
6+
- 设置占位变量 groupId、artifactId、version。
7+
- 使用 ApiClient 与 RecordsApi 调用接口。
8+
9+
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?xml version="1.0"?>
2+
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"
3+
xmlns="http://maven.apache.org/POM/4.0.0"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
5+
<modelVersion>4.0.0</modelVersion>
6+
<groupId>${groupId}</groupId>
7+
<artifactId>${artifactId}</artifactId>
8+
<version>${version}</version>
9+
<name>${artifactId}</name>
10+
11+
<properties>
12+
<maven.compiler.source>17</maven.compiler.source>
13+
<maven.compiler.target>17</maven.compiler.target>
14+
<jackson.version>2.17.1</jackson.version>
15+
</properties>
16+
17+
<dependencies>
18+
<dependency>
19+
<groupId>com.fasterxml.jackson.core</groupId>
20+
<artifactId>jackson-databind</artifactId>
21+
<version>${jackson.version}</version>
22+
</dependency>
23+
<dependency>
24+
<groupId>com.fasterxml.jackson.datatype</groupId>
25+
<artifactId>jackson-datatype-jsr310</artifactId>
26+
<version>${jackson.version}</version>
27+
</dependency>
28+
</dependencies>
29+
30+
<build>
31+
<plugins>
32+
<plugin>
33+
<artifactId>maven-compiler-plugin</artifactId>
34+
<version>3.14.0</version>
35+
<configuration>
36+
<parameters>true</parameters>
37+
</configuration>
38+
</plugin>
39+
</plugins>
40+
</build>
41+
</project>
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package ${packageName};
2+
3+
public enum Direction {
4+
ASC, DESC
5+
}
6+
7+
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package ${packageName};
2+
3+
import java.util.List;
4+
5+
public class PageResult<T> {
6+
private long total;
7+
private List<T> list;
8+
9+
public long getTotal() {
10+
return total;
11+
}
12+
13+
public void setTotal(long total) {
14+
this.total = total;
15+
}
16+
17+
public List<T> getList() {
18+
return list;
19+
}
20+
21+
public void setList(List<T> list) {
22+
this.list = list;
23+
}
24+
}
25+
26+
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
package ${packageName};
2+
3+
import com.fasterxml.jackson.core.type.TypeReference;
4+
5+
import java.util.HashMap;
6+
import java.util.List;
7+
import java.util.Map;
8+
import ${packageName}.client.ApiClient;
9+
import ${packageName}.client.ApiClient;
10+
11+
12+
public class RecordsApi {
13+
private final ApiClient apiClient;
14+
15+
public RecordsApi(ApiClient apiClient) {
16+
this.apiClient = apiClient;
17+
}
18+
19+
public ApiResponse<PageResult<Map<String, Object>>> listRecords(
20+
String datasourceName,
21+
String modelName,
22+
Integer current,
23+
Integer pageSize,
24+
String filter,
25+
Boolean nestedQuery,
26+
String sort
27+
) {
28+
String path = String.format(
29+
"/api/f/datasources/%s/models/%s/records",
30+
encode(datasourceName), encode(modelName)
31+
);
32+
Map<String, Object> q = new HashMap<>();
33+
if (current != null) q.put("current", current);
34+
if (pageSize != null) q.put("pageSize", pageSize);
35+
if (filter != null) q.put("filter", filter);
36+
if (nestedQuery != null) q.put("nestedQuery", nestedQuery);
37+
if (sort != null) q.put("sort", sort);
38+
39+
PageResult<Map<String, Object>> data = apiClient.get(
40+
path, q, new TypeReference<PageResult<Map<String, Object>>>() {}
41+
);
42+
return new ApiResponse<>(200, data);
43+
}
44+
45+
public Map<String, Object> createRecord(
46+
String datasourceName,
47+
String modelName,
48+
Map<String, Object> body
49+
) {
50+
String path = String.format(
51+
"/api/f/datasources/%s/models/%s/records",
52+
encode(datasourceName), encode(modelName)
53+
);
54+
return apiClient.post(path, body, new TypeReference<Map<String, Object>>() {});
55+
}
56+
57+
public Map<String, Object> getRecord(
58+
String datasourceName,
59+
String modelName,
60+
String id,
61+
Boolean nestedQuery
62+
) {
63+
String path = String.format(
64+
"/api/f/datasources/%s/models/%s/records/%s",
65+
encode(datasourceName), encode(modelName), encode(id)
66+
);
67+
Map<String, Object> q = new HashMap<>();
68+
if (nestedQuery != null) q.put("nestedQuery", nestedQuery);
69+
return apiClient.get(path, q, new TypeReference<Map<String, Object>>() {});
70+
}
71+
72+
public Map<String, Object> updateRecord(
73+
String datasourceName,
74+
String modelName,
75+
String id,
76+
Map<String, Object> body
77+
) {
78+
String path = String.format(
79+
"/api/f/datasources/%s/models/%s/records/%s",
80+
encode(datasourceName), encode(modelName), encode(id)
81+
);
82+
return apiClient.put(path, body, new TypeReference<Map<String, Object>>() {});
83+
}
84+
85+
public Map<String, Object> patchRecord(
86+
String datasourceName,
87+
String modelName,
88+
String id,
89+
Map<String, Object> body
90+
) {
91+
String path = String.format(
92+
"/api/f/datasources/%s/models/%s/records/%s",
93+
encode(datasourceName), encode(modelName), encode(id)
94+
);
95+
return apiClient.patch(path, body, new TypeReference<Map<String, Object>>() {});
96+
}
97+
98+
public void deleteRecord(
99+
String datasourceName,
100+
String modelName,
101+
String id
102+
) {
103+
String path = String.format(
104+
"/api/f/datasources/%s/models/%s/records/%s",
105+
encode(datasourceName), encode(modelName), encode(id)
106+
);
107+
apiClient.delete(path);
108+
}
109+
110+
private String encode(String s) {
111+
return s.replace("/", "%2F");
112+
}
113+
}
114+
115+
Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
package ${packageName};
2+
3+
import com.fasterxml.jackson.core.type.TypeReference;
4+
import com.fasterxml.jackson.databind.DeserializationFeature;
5+
import com.fasterxml.jackson.databind.ObjectMapper;
6+
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
7+
8+
import java.io.IOException;
9+
import java.net.URI;
10+
import java.net.URLEncoder;
11+
import java.net.http.HttpClient;
12+
import java.net.http.HttpRequest;
13+
import java.net.http.HttpResponse;
14+
import java.nio.charset.StandardCharsets;
15+
import java.time.Duration;
16+
import java.util.HashMap;
17+
import java.util.Map;
18+
import java.util.StringJoiner;
19+
20+
public class ApiClient {
21+
private final String baseUrl;
22+
private final HttpClient httpClient;
23+
private final ObjectMapper objectMapper;
24+
private final Map<String, String> defaultHeaders = new HashMap<>();
25+
26+
public ApiClient(String baseUrl) {
27+
this(baseUrl, HttpClient.newBuilder().connectTimeout(Duration.ofSeconds(10)).build());
28+
}
29+
30+
public ApiClient(String baseUrl, HttpClient httpClient) {
31+
this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
32+
this.httpClient = httpClient;
33+
this.objectMapper = new ObjectMapper()
34+
.registerModule(new JavaTimeModule())
35+
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
36+
this.defaultHeaders.put("Content-Type", "application/json");
37+
this.defaultHeaders.put("Accept", "application/json");
38+
}
39+
40+
public ApiClient setDefaultHeader(String name, String value) {
41+
this.defaultHeaders.put(name, value);
42+
return this;
43+
}
44+
45+
public <T> T get(String path, Map<String, Object> query, TypeReference<T> typeRef) {
46+
HttpRequest request = baseRequest("GET", buildUrl(path, query), null);
47+
return send(request, typeRef);
48+
}
49+
50+
public <T> T post(String path, Object body, TypeReference<T> typeRef) {
51+
HttpRequest request = baseRequest("POST", buildUrl(path, null), serialize(body));
52+
return send(request, typeRef);
53+
}
54+
55+
public <T> T put(String path, Object body, TypeReference<T> typeRef) {
56+
HttpRequest request = baseRequest("PUT", buildUrl(path, null), serialize(body));
57+
return send(request, typeRef);
58+
}
59+
60+
public <T> T patch(String path, Object body, TypeReference<T> typeRef) {
61+
HttpRequest request = baseRequest("PATCH", buildUrl(path, null), serialize(body));
62+
return send(request, typeRef);
63+
}
64+
65+
public void delete(String path) {
66+
HttpRequest request = baseRequest("DELETE", buildUrl(path, null), null);
67+
send(request, new TypeReference<Void>() {});
68+
}
69+
70+
private HttpRequest baseRequest(String method, String url, String body) {
71+
HttpRequest.Builder builder = HttpRequest.newBuilder()
72+
.uri(URI.create(url))
73+
.timeout(Duration.ofSeconds(30));
74+
75+
for (Map.Entry<String, String> e : defaultHeaders.entrySet()) {
76+
builder.header(e.getKey(), e.getValue());
77+
}
78+
79+
if ("GET".equals(method) || body == null) {
80+
builder.method(method, HttpRequest.BodyPublishers.noBody());
81+
} else {
82+
builder.method(method, HttpRequest.BodyPublishers.ofString(body));
83+
}
84+
return builder.build();
85+
}
86+
87+
private String buildUrl(String path, Map<String, Object> query) {
88+
StringBuilder sb = new StringBuilder();
89+
sb.append(baseUrl);
90+
if (!path.startsWith("/")) sb.append('/');
91+
sb.append(path);
92+
if (query != null && !query.isEmpty()) {
93+
StringJoiner joiner = new StringJoiner("&");
94+
for (Map.Entry<String, Object> e : query.entrySet()) {
95+
if (e.getValue() == null) continue;
96+
joiner.add(encode(e.getKey()) + "=" + encode(String.valueOf(e.getValue())));
97+
}
98+
String qs = joiner.toString();
99+
if (!qs.isEmpty()) sb.append('?').append(qs);
100+
}
101+
return sb.toString();
102+
}
103+
104+
private String encode(String s) {
105+
return URLEncoder.encode(s, StandardCharsets.UTF_8);
106+
}
107+
108+
private String serialize(Object value) {
109+
try {
110+
return objectMapper.writeValueAsString(value == null ? new HashMap<>() : value);
111+
} catch (IOException e) {
112+
throw new RuntimeException(e);
113+
}
114+
}
115+
116+
private <T> T send(HttpRequest request, TypeReference<T> typeRef) {
117+
try {
118+
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
119+
int code = response.statusCode();
120+
String body = response.body();
121+
if (code >= 200 && code < 300) {
122+
if (typeRef.getType().getTypeName().equals(Void.class.getTypeName())) {
123+
return null;
124+
}
125+
return objectMapper.readValue(body, typeRef);
126+
}
127+
throw new ApiException(code, "HTTP " + code, body);
128+
} catch (IOException | InterruptedException e) {
129+
throw new RuntimeException(e);
130+
}
131+
}
132+
}
133+
134+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package ${packageName};
2+
3+
public class ApiException extends RuntimeException {
4+
private final int statusCode;
5+
private final String responseBody;
6+
7+
public ApiException(int statusCode, String message, String responseBody) {
8+
super(message);
9+
this.statusCode = statusCode;
10+
this.responseBody = responseBody;
11+
}
12+
13+
public int getStatusCode() {
14+
return statusCode;
15+
}
16+
17+
public String getResponseBody() {
18+
return responseBody;
19+
}
20+
}
21+
22+

0 commit comments

Comments
 (0)