Browse Source

增加JAVA 21 版本

master
zhanglei 1 month ago
parent
commit
e88d24c92a
  1. 121
      generator.py
  2. 141
      templates/21.FilesUtil.java.j2
  3. 190
      templates/21.MinioUpComponent.java.j2
  4. 44
      templates/21.SaTokenConfig.java.j2
  5. 45
      templates/21.SwaggerConfig.java.j2
  6. 107
      templates/21.controller.java.j2
  7. 283
      templates/21.main.pom.xml.j2
  8. 265
      templates/21.project.pom.xml.j2
  9. 85
      templates/21.webLogAspect.java.j2
  10. 0
      templates/SaTokenConfig.java.j2
  11. 2
      templates/SwaggerConfig.java.j2
  12. 8
      utils.py

121
generator.py

@ -1,12 +1,13 @@
import logging import logging
import os import os
from datetime import datetime from datetime import datetime
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader,TemplateNotFound
# from config import * # from config import *
from db import get_table, get_columns from db import get_table, get_columns
from utils import * from utils import *
import argparse import argparse
import yaml import yaml
import re
env = Environment(loader=FileSystemLoader("templates")) env = Environment(loader=FileSystemLoader("templates"))
@ -24,28 +25,60 @@ def build_fields(table_name):
}) })
return fields return fields
def render(template_name, out_path, context, overwrite=False): def render(template_name, out_path, context, java_version, overwrite=False):
""" """
:param template_name: 模板文件名 :param template_name: 模板文件名
:param out_path: 输出文件路径 :param out_path: 输出文件路径
:param context: 渲染上下文 :param context: 渲染上下文
:param overwrite: 是否覆盖已存在文件默认 False :param overwrite: 是否覆盖已存在文件默认 False
""" """
# 文件存在且不允许覆盖 → 直接跳过
# 文件存在且不允许覆盖 → 跳过
if os.path.exists(out_path) and not overwrite: if os.path.exists(out_path) and not overwrite:
logging.info("Skip exists file: %s", out_path) logging.info("Skip exists file: %s", out_path)
return return
tpl = env.get_template(template_name) if java_version != "":
template_name = java_version+"."+template_name
real_template = template_name
print(">>>>template_name:", template_name)
# 1️⃣ 尝试原模板
try:
env.loader.get_source(env, real_template)
except TemplateNotFound:
# 2️⃣ 去掉数字前缀,如 21.controller.java.j2 → controller.java.j2
fallback = re.sub(r"^\d+\.", "", template_name)
if fallback != template_name:
try:
env.loader.get_source(env, fallback)
logging.warning(
"Template not found: %s, fallback to %s",
template_name, fallback
)
real_template = fallback
except TemplateNotFound:
raise FileNotFoundError(
f"Template not found: {template_name} and fallback {fallback}"
)
else:
raise FileNotFoundError(f"Template not found: {template_name}")
# 3️⃣ 正式渲染
tpl = env.get_template(real_template)
content = tpl.render(**context) content = tpl.render(**context)
os.makedirs(os.path.dirname(out_path), exist_ok=True) os.makedirs(os.path.dirname(out_path), exist_ok=True)
with open(out_path, "w", encoding="utf-8") as f: with open(out_path, "w", encoding="utf-8") as f:
f.write(content) f.write(content)
logging.info("Generated file: %s", out_path) logging.info("Generated file: %s (template: %s)", out_path, real_template)
def generate(table_names: list[str], model_names: list[str], conf_name: str, over_write: bool):
def generate(table_names: list[str], model_names: list[str], conf_name: str, over_write: bool, java_version: str):
# context = { # context = {
# "mainModule": MAIN_MODULE, # "mainModule": MAIN_MODULE,
@ -119,6 +152,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
"entity.java.j2", "entity.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/entity/{entity}.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/entity/{entity}.java",
context, context,
java_version,
over_write over_write
) )
@ -126,6 +160,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
"controller.java.j2", "controller.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/controller/{entity}Controller.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/controller/{entity}Controller.java",
context, context,
java_version,
over_write over_write
) )
@ -133,6 +168,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
"service.java.j2", "service.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/service/{entity}Service.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/service/{entity}Service.java",
context, context,
java_version,
over_write over_write
) )
@ -140,6 +176,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
"serviceImpl.java.j2", "serviceImpl.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/service/impl/{entity}MPJBaseServiceImpl.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/service/impl/{entity}MPJBaseServiceImpl.java",
context, context,
java_version,
over_write over_write
) )
@ -147,6 +184,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
"mapper.java.j2", "mapper.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/mapper/{entity}Mapper.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/mapper/{entity}Mapper.java",
context, context,
java_version,
over_write over_write
) )
@ -154,6 +192,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
"mapper.xml.j2", "mapper.xml.j2",
f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/mappers/{entity}Mapper.xml", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/mappers/{entity}Mapper.xml",
context, context,
java_version,
over_write over_write
) )
@ -162,28 +201,32 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
render( render(
"baseEntity.java.j2", "baseEntity.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/entity/BaseEntity.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/entity/BaseEntity.java",
context context,
java_version
) )
# common MybatisPlusConfig # common MybatisPlusConfig
render( render(
"mybatisPlusConfig.java.j2", "mybatisPlusConfig.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/MybatisPlusConfig.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/MybatisPlusConfig.java",
context context,
java_version
) )
# common MybatisPlusConfig # common MybatisPlusConfig
render( render(
"webLogAspect.java.j2", "webLogAspect.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/WebLogAspect.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/WebLogAspect.java",
context context,
java_version
) )
# common 基础输出result # common 基础输出result
render( render(
"result.java.j2", "result.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/vo/Result.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/vo/Result.java",
context context,
java_version
) )
#Util 公共功能 #Util 公共功能
@ -191,56 +234,64 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
render( render(
file, file,
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/unit/{file.replace('.j2', '')}", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/unit/{file.replace('.j2', '')}",
context context,
java_version
) )
# application 启动的方法 # application 启动的方法
render( render(
"application.java.j2", "application.java.j2",
f"{BASE_DIR}{MAIN_BASE_PACKAGE_DIR}/Application.java", f"{BASE_DIR}{MAIN_BASE_PACKAGE_DIR}/Application.java",
context context,
java_version
) )
# test 测试类 # test 测试类
render( render(
"applicationTests.java.j2", "applicationTests.java.j2",
f"{BASE_DIR}{OUTPUT_DIR}/test/{to_path(BASE_PACKAGE)}/ApplicationTests.java", f"{BASE_DIR}{OUTPUT_DIR}/test/{to_path(BASE_PACKAGE)}/ApplicationTests.java",
context context,
java_version
) )
# 主pom文件 # 主pom文件
render( render(
"main.pom.xml.j2", "main.pom.xml.j2",
f"{BASE_DIR}{MAIN_MODULE}/pom.xml", f"{BASE_DIR}{MAIN_MODULE}/pom.xml",
context context,
java_version
) )
# 子项目pom文件 # 子项目pom文件
render( render(
"project.pom.xml.j2", "project.pom.xml.j2",
f"{BASE_DIR}{MAIN_MODULE}/{MODULE_NAME}/pom.xml", f"{BASE_DIR}{MAIN_MODULE}/{MODULE_NAME}/pom.xml",
context context,
java_version
) )
#项目的yml配置文件 resources 生成环境配置为了最低限度能将项目跑起来 #项目的yml配置文件 resources 生成环境配置为了最低限度能将项目跑起来
render( render(
"application.yml.j2", "application.yml.j2",
f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/application.yml", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/application.yml",
context context,
java_version
) )
#项目开发环境的yml配置文件 resources yml 只生成dev环境配置为了最低限度能将项目跑起来 #项目开发环境的yml配置文件 resources yml 只生成dev环境配置为了最低限度能将项目跑起来
render( render(
"application-dev.yml.j2", "application-dev.yml.j2",
f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/application-dev.yml", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/application-dev.yml",
context context,
java_version
) )
#项目开发环境的yml配置文件 resources yml 只生成dev环境配置为了最低限度能将项目跑起来 #项目开发环境的yml配置文件 resources yml 只生成dev环境配置为了最低限度能将项目跑起来
render( render(
"logback.xml.j2", "logback.xml.j2",
f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/logback.xml", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/logback.xml",
context context,
java_version
) )
# ========= 功能模块 ========= # ========= 功能模块 =========
@ -249,51 +300,59 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove
case "swagger": case "swagger":
# common Swagger2 # common Swagger2
render( render(
"swagger2.java.j2", "SwaggerConfig.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/Swagger2.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/Swagger2.java",
context context,
java_version
) )
case "saToken": case "saToken":
# common GlobalException soToken 报错自定义 # common GlobalException soToken 报错自定义
render( render(
"globalException.java.j2", "globalException.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/GlobalException.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/GlobalException.java",
context context,
java_version
) )
render( render(
"saTokenConfigure.java.j2", "SaTokenConfig.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/SaTokenConfig.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/SaTokenConfig.java",
context context,
java_version
) )
case "minio": case "minio":
#MinioConfig #MinioConfig
render( render(
"MinioConfig.java.j2", "MinioConfig.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/MinioConfig.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/MinioConfig.java",
context context,
java_version
) )
render( render(
"MinioUpController.java.j2", "MinioUpController.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/controller/MinioUpController.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/controller/MinioUpController.java",
context context,
java_version
) )
render( render(
"MinioUpComponent.java.j2", "MinioUpComponent.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/unit/MinioUpComponent.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/unit/MinioUpComponent.java",
context context,
java_version
) )
case "xxlJob": case "xxlJob":
# common XxlJobConfig # common XxlJobConfig
render( render(
"xxlJobConfig.java.j2", "xxlJobConfig.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/XxlJobConfig.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/XxlJobConfig.java",
context context,
java_version
) )
# common xxjob的测试类 # common xxjob的测试类
render( render(
"testJob.java.j2", "testJob.java.j2",
f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/job/TestJob.java", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/job/TestJob.java",
context context,
java_version
) )
if __name__ == "__main__": if __name__ == "__main__":
@ -302,11 +361,13 @@ if __name__ == "__main__":
tables = [t.strip() for t in args.tab.split(",") if t.strip()] tables = [t.strip() for t in args.tab.split(",") if t.strip()]
models = [m.strip() for m in args.model.split(",") if m.strip()] models = [m.strip() for m in args.model.split(",") if m.strip()]
conf = args.conf conf = args.conf
re = args.re version = args.jdk
rew = args.rew
generate( generate(
table_names=tables, table_names=tables,
model_names=models, model_names=models,
conf_name=conf, conf_name=conf,
over_write=re java_version=version,
over_write=rew
) )

141
templates/21.FilesUtil.java.j2

@ -0,0 +1,141 @@
package {{ package.Common }}.unit;
import org.apache.commons.io.FileUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.*;
import java.util.Base64;
public class FilesUtil {
/**
* 根据文件路径获取文件字节流
* @return
* filePath 文件路径
* @throws IOException
*/
public static byte[] toByteArray(String filePath) throws IOException {
File f = new File(filePath);
if (!f.exists()) {
throw new FileNotFoundException("文件不存在");
}
ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
BufferedInputStream in = null;
try {
in = new BufferedInputStream(new FileInputStream(f));
int buf_size = 1024;
byte[] buffer = new byte[buf_size];
int len = 0;
while (-1 != (len = in.read(buffer, 0, buf_size))) {
bos.write(buffer, 0, len);
}
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
throw e;
} finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
bos.close();
}
}
public static File multipartFileToFile(MultipartFile file) throws Exception {
File toFile = null;
if (file.equals("") || file.getSize() <= 0) {
file = null;
} else {
InputStream ins = null;
ins = file.getInputStream();
toFile = new File(file.getOriginalFilename());
inputStreamToFile(ins, toFile);
ins.close();
}
return toFile;
}
private static void inputStreamToFile(InputStream ins, File file) {
try {
OutputStream os = new FileOutputStream(file);
int bytesRead = 0;
byte[] buffer = new byte[8192];
while ((bytesRead = ins.read(buffer, 0, 8192)) != -1) {
os.write(buffer, 0, bytesRead);
}
os.close();
ins.close();
} catch (Exception e) {
e.printStackTrace();
}
}
public static String TransformPhotoToBase64Data(String path){
Base64.Encoder encoder= Base64.getEncoder(); //获取Base64编码器
byte [] ImgContainer = null ; //数据集缓存器
FileInputStream fileInputStream = null; //文件输入流
try {
System.out.println(path);
File file=new File(path);
fileInputStream = new FileInputStream(file); //到指定路径寻找文件
ImgContainer = new byte[fileInputStream.available()]; //设置图片字节数据缓冲区大小
fileInputStream.read(ImgContainer); //将数据流中的图片数据读进缓冲区
String Base64ImgData =encoder.encodeToString(ImgContainer); //将图片编码转换成Base64格式的数据集
fileInputStream.close(); //关闭数据流
return Base64ImgData; //将缓冲区数据转换成字符数据返回
} catch (FileNotFoundException e) {
return "找不到指定文件!";
} catch (IOException e) {
e.printStackTrace();
}
return "null";
}
public static String getBase64String(MultipartFile multiPartFile) throws IOException {
String baseStr = null;
//把MultipartFile转化为File
File file = new File(multiPartFile.getOriginalFilename());
FileUtils.copyInputStreamToFile(multiPartFile.getInputStream(), file);
try {//file转base64
FileInputStream inputStream = new FileInputStream(file);
byte[] buffer = new byte[(int) file.length()];
inputStream.read(buffer);
inputStream.close();
baseStr = Base64.getEncoder().encodeToString(buffer);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
//删除临时文件
if (file.exists()) {
file.delete();
}
baseStr = baseStr.replaceAll("\r\n", "");
return baseStr;
}
/**
* 返回文件扩展名,带。
* @param file
* @return
*/
public static String getFileExtension(MultipartFile file) {
String fileName = file.getOriginalFilename();
int dotIndex = fileName.lastIndexOf(".");
if (dotIndex == -1) {
return "";
} else {
return "."+fileName.substring(dotIndex + 1);
}
}
}

190
templates/21.MinioUpComponent.java.j2

@ -0,0 +1,190 @@
package {{ package.Common }}.unit;
import {{ package.Common }}.config.MinioConfig;
import io.minio.*;
import io.minio.http.Method;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.TimeUnit;
/****
* @Description: 上传 文件组件
* @Author: {{author}}
* @Date: {{date}}
* @Wechat: {{ wechat }}
*/
@Slf4j
@Component
public class MinioUpComponent {
private final static String separator = "/";
@Autowired
private MinioConfig minioConfig;
@Autowired
private MinioClient minioClient;
/**
* @param dirPath
* @param filename yyyy/mm/dd/file.jpg
* @return
*/
public static String builderFilePath(String dirPath, String filename) {
StringBuilder stringBuilder = new StringBuilder(50);
if (!StringUtils.isEmpty(dirPath)) {
stringBuilder.append(dirPath).append(separator);
}
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
String todayStr = sdf.format(new Date());
stringBuilder.append(todayStr).append(separator);
stringBuilder.append(filename);
return stringBuilder.toString();
}
/**
* 上传图片文件
*
* @param prefix 文件前缀
* @param filename 文件名
* @param inputStream 文件流
* @return 文件全路径
*/
public String uploadImg(String prefix, String filename, InputStream inputStream) {
String filePath = builderFilePath(prefix, filename);
try {
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.object(filePath)
.contentType("image/jpg")
.bucket(minioConfig.getBucketName()).stream(inputStream, inputStream.available(), -1)
.build();
minioClient.putObject(putObjectArgs);
StringBuilder urlPath = new StringBuilder(minioConfig.getReadPath());
urlPath.append(separator + minioConfig.getBucketName());
urlPath.append(separator);
urlPath.append(filePath);
return urlPath.toString();
} catch (Exception ex) {
log.error("minio put file error.", ex);
throw new RuntimeException("上传文件失败");
}
}
/**
* 上传html文件
*
* @param prefix 文件前缀
* @param filename 文件名
* @param inputStream 文件流
* @return 文件全路径
*/
public String uploadHtml(String prefix, String filename, InputStream inputStream) {
String filePath = builderFilePath(prefix, filename);
try {
PutObjectArgs putObjectArgs = PutObjectArgs.builder()
.object(filePath)
.contentType("text/html")
.bucket(minioConfig.getBucketName())
.stream(inputStream, inputStream.available(), -1)
.build();
minioClient.putObject(putObjectArgs);
StringBuilder urlPath = new StringBuilder(minioConfig.getReadPath());
urlPath.append(separator + minioConfig.getBucketName());
urlPath.append(separator);
urlPath.append(filePath);
return urlPath.toString();
} catch (Exception ex) {
log.error("minio put file error.", ex);
ex.printStackTrace();
throw new RuntimeException("上传文件失败");
}
}
/**
* 防盗链接有效期按分钟
*
* @param filePath 文件前缀
* @param expiry 超时分钟
* @return 文件全路径
*/
public String getPresignObjectUrl(String filePath, Integer expiry) {
try {
filePath = filePath.replace("http://health.reglory.com.cn:9001/health-bucket/", "");
GetPresignedObjectUrlArgs putObjectArgs = GetPresignedObjectUrlArgs.builder()
.object(filePath)
.bucket(minioConfig.getBucketName())
.method(Method.GET)
// .region("health.reglory.com.cn:9001")
.expiry(expiry, TimeUnit.MINUTES)
.build();
return minioClient.getPresignedObjectUrl(putObjectArgs);
} catch (Exception ex) {
log.error("minio put file error.", ex);
ex.printStackTrace();
throw new RuntimeException("上传文件失败");
}
}
/**
* 删除文件
*
* @param pathUrl 文件全路径
*/
public void delete(String pathUrl) {
String key = pathUrl.replace(minioConfig.getEndpoint() + "/", "");
int index = key.indexOf(separator);
String bucket = key.substring(0, index);
String filePath = key.substring(index + 1);
// 删除Objects
RemoveObjectArgs removeObjectArgs = RemoveObjectArgs.builder().bucket(bucket).object(filePath).build();
try {
minioClient.removeObject(removeObjectArgs);
} catch (Exception e) {
log.error("minio remove file error. pathUrl:{}", pathUrl);
e.printStackTrace();
}
}
/**
* 下载文件
*
* @param pathUrl 文件全路径
* @return 文件流
*/
public byte[] downLoadFile(String pathUrl) {
String key = pathUrl.replace(minioConfig.getEndpoint() + "/", "");
int index = key.indexOf(separator);
//String bucket = key.substring(0, index);
String filePath = key.substring(index + 1);
InputStream inputStream = null;
try {
inputStream = minioClient.getObject(
GetObjectArgs.builder().bucket(minioConfig.getBucketName()).object(filePath).build()
);
} catch (Exception e) {
log.error("minio down file error. pathUrl:{}", pathUrl);
e.printStackTrace();
}
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
byte[] buff = new byte[100];
int rc = 0;
while (true) {
try {
if (!((rc = inputStream.read(buff, 0, 100)) > 0)) break;
} catch (IOException e) {
e.printStackTrace();
}
byteArrayOutputStream.write(buff, 0, rc);
}
return byteArrayOutputStream.toByteArray();
}
}

44
templates/21.SaTokenConfig.java.j2

@ -0,0 +1,44 @@
package {{ package.Common }}.config;
import cn.dev33.satoken.interceptor.SaInterceptor;
import cn.dev33.satoken.router.SaRouter;
import cn.dev33.satoken.stp.StpUtil;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import jakarta.annotation.Resource;
import java.util.List;
/**
* SaToken配置
* @Author: {{author}}
* @Date: {{date}}
* @Wechat: {{ wechat }}
* 解决@RequestAttribute、@RequestParam和@RequestBody三种类型的时间类型参数接收与转换问题
*/
@Configuration
public class SaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册 Sa-Token 拦截器,定义详细认证规则
registry.addInterceptor(new SaInterceptor(handler -> {
// 指定一条 match 规则
SaRouter
.match("/models/**") // 拦截的 path 列表,可以写多个 */
// .notMatch("/models/health-user/login") // 排除掉的 path 列表,可以写多个
.check(r -> StpUtil.checkLogin()); // 要执行的校验动作,可以写完整的 lambda 表达式
//拦截并写操作日志
// SaRouter.match(r).check(t->{
// SaLog.info("操作日志:{}", SaLog.getParamJson());
// SaLog.info("操作日志:{}", SaLog.getRequestBody());
// );
})).addPathPatterns("/**");
}
}

45
templates/21.SwaggerConfig.java.j2

@ -0,0 +1,45 @@
package {{ package.Common }}.config;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Swagger3 / OpenAPI 配置
*
* @Author: snail
* @Date: 2026-02-06
* @Wechat: ot_bus
*
* 访问地址:
* http://localhost:port/swagger-ui/index.html
*/
@Configuration
public class SwaggerConfig {
@Value("${swagger.show:true}")
private boolean swaggerShow;
@Bean
public OpenAPI openAPI() {
if (!swaggerShow) {
// 生产环境关闭文档
return new OpenAPI();
}
return new OpenAPI()
.info(new Info()
.title("数据中心接口文档")
.description("数据中心相关接口文档")
.version("1.0")
.contact(new Contact()
.name("snail")
.url("https://www.deepseek.com/")
.email("")
)
);
}
}

107
templates/21.controller.java.j2

@ -0,0 +1,107 @@
package {{ package.Controller }};
import {{ package.Entity }}.{{ table.entity }};
import {{ package.Service }}.{{ table.entity }}Service;
import {{ package.Common }}.vo.Result;
//--- import 固定引入 ---//
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.web.bind.annotation.*;
import jakarta.annotation.Resource;
import jakarta.validation.Valid;
import java.util.List;
//--- import 固定引入 ---//
/**
* <p>
* {{ table.comment }} 前端控制器
* </p>
* @Author: {{author}}
* @Date: {{date}}
* @Wechat: {{ wechat }}
*/
@Api(tags = "{{ table.comment }}")
{% if restControllerStyle %}
@RestController
{% else %}
@Controller
{% endif %}
@RequestMapping("{{ table.name }}")
public class {{ table.entity }}Controller {
@Resource
private {{ table.entity }}Service {{table.lowerEntity}}Service;
@ApiOperation(value = "{{ table.comment }}分页列表查询", response = {{ table.entity }}.class)
@PostMapping(value = "/page")
public Result<Page<{{ table.entity }}>> page(@Valid @RequestBody {{ table.entity }} param,@RequestHeader("token") String token,
@RequestHeader(value = "version", defaultValue = "1.0") String version) {
Page<{{ table.entity }}> page = {{table.lowerEntity}}Service.page(param);
return Result.OK(page);
}
@ApiOperation(value = "{{ table.comment }}根据条件查询")
@PostMapping(value = "/info")
public Result<Object> info(@Valid @RequestBody {{ table.entity }} param,
@RequestHeader("token") String token,
@RequestHeader(value = "version", defaultValue = "1.0") String version) {
if (token ==null) {
return Result.error("token不能为空");
}
{{ table.entity }} data = {{table.lowerEntity}}Service.info(param);
return Result.OK(data);
}
@ApiOperation(value = "{{ table.comment }}新增")
@PostMapping(value = "/add")
public Result add(@Valid @RequestBody {{ table.entity }} param,
@RequestHeader("token") String token,
@RequestHeader(value = "version", defaultValue = "1.0") String version) {
if (token ==null) {
return Result.error("token不能为空");
}
{{table.lowerEntity}}Service.add(param);
return Result.OK();
}
@ApiOperation(value = "{{ table.comment }}修改")
@PostMapping(value = "/modify")
public Result modify(@Valid @RequestBody {{ table.entity }} param,
@RequestHeader("token") String token,
@RequestHeader(value = "version", defaultValue = "1.0") String version) {
if (token ==null) {
return Result.error("token不能为空");
}
{{table.entity}} info = {{table.lowerEntity}}Service.info(Integer.valueOf(param.getId()));
if (info ==null) {
return Result.error(String.format("[%s]记录不存在", info));
}
{{table.lowerEntity}}Service.modify(param);
return Result.OK();
}
@ApiOperation(value = "{{ table.comment }}删除(单个条目)")
@GetMapping(value = "/remove/{id}")
public Result remove(@PathVariable Integer id,
@RequestHeader("token") String token,
@RequestHeader(value = "version", defaultValue = "1.0") String version) {
{{table.lowerEntity}}Service.remove(id);
return Result.OK();
}
@ApiOperation(value = "{{ table.comment }}删除(多个条目)")
@PostMapping(value = "/removes")
public Result removes(@Valid @RequestBody List<Integer> ids,
@RequestHeader("token") String token,
@RequestHeader(value = "version", defaultValue = "1.0") String version) {
{{table.lowerEntity}}Service.removes(ids);
return Result.OK();
}
}

283
templates/21.main.pom.xml.j2

@ -0,0 +1,283 @@
<?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>
<groupId>{{ groupId }}</groupId>
<artifactId>{{ mainModule }}</artifactId>
<version>1.0.0</version>
<name>${project.artifactId}</name>
<packaging>pom</packaging>
<modules>
<module>{{ moduleName }}</module>
</modules>
<properties>
<spring-boot.version>3.1.10</spring-boot.version>
<spring-cloud.version>2022.0.5</spring-cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>21</java.version>
<maven.compiler.release>21</maven.compiler.release>
<!-- 常用工具版本 -->
<hutool.version>5.8.25</hutool.version>
<fastjson2.version>2.0.48</fastjson2.version>
<druid.version>1.2.20</druid.version>
<mybatisplus.version>3.5.6</mybatisplus.version>
<!-- 数据库驱动 -->
<mysql.version>8.0.33</mysql.version>
<postgresql.version>42.6.0</postgresql.version>
<!-- 中间件和网络 -->
<netty.version>4.1.104.Final</netty.version>
<minio.version>8.5.7</minio.version>
<jedis.version>4.3.1</jedis.version>
<!-- Apache 工具 -->
<poi.version>5.2.5</poi.version>
<commons-pool2.version>2.11.1</commons-pool2.version>
<commons-net.version>3.10.0</commons-net.version>
<!-- 其他框架 -->
<shiro.version>1.13.0</shiro.version>
<sa-token.version>1.38.0</sa-token.version>
<springdoc.version>2.2.0</springdoc.version>
<!-- 插件版本 -->
<maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
</properties>
<!-- 添加阿里云仓库 -->
<repositories>
<repository>
<id>aliyun</id>
<name>Aliyun Maven</name>
<url>https://maven.aliyun.com/repository/public</url>
<releases>
<enabled>true</enabled>
</releases>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
<repository>
<id>jitpack.io</id>
<name>JitPack Repository</name>
<url>https://jitpack.io</url>
</repository>
</repositories>
<dependencyManagement>
<dependencies>
<!-- Spring Boot BOM -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- Spring Cloud BOM -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- 明确声明常用依赖的版本 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>${hutool.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
<version>${fastjson2.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>${mybatisplus.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
<version>${netty.version}</version>
</dependency>
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
<version>${minio.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>${poi.version}</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>${commons-net.version}</version>
</dependency>
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
<version>${shiro.version}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
<version>${sa-token.version}</version>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
<version>${sa-token.version}</version>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc.version}</version>
</dependency>
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
<version>2.3.2</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
<version>4.6.4</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-iot</artifactId>
<version>7.7.0</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
<version>1.4.13</version>
</dependency>
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-core</artifactId>
<version>1.4.13</version>
</dependency>
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
<version>2.4.1</version>
</dependency>
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
<version>1.6.2</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- 所有子模块都会继承的基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>${spring-boot.version}</version>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<release>${java.version}</release>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
</plugins>
</pluginManagement>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>

265
templates/21.project.pom.xml.j2

@ -0,0 +1,265 @@
<?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>{{ groupId }}</groupId>
<artifactId>{{ mainModule }}</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>{{ moduleName }}</artifactId>
<name>{{ moduleName }}</name>
<dependencies>
<!-- Spring Boot 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<!-- 数据库相关 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-3-starter</artifactId>
</dependency>
<!-- MyBatis Plus -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
</dependency>
<!-- <dependency>-->
<!-- <groupId>com.baomidou</groupId>-->
<!-- <artifactId>mybatis-plus-generator</artifactId>-->
<!-- </dependency>-->
<!-- MyBatis Plus Join -->
<dependency>
<groupId>com.github.yulichang</groupId>
<artifactId>mybatis-plus-join-boot-starter</artifactId>
</dependency>
<!-- Redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<!-- Netty -->
<dependency>
<groupId>io.netty</groupId>
<artifactId>netty-all</artifactId>
</dependency>
<!-- MinIO -->
<dependency>
<groupId>io.minio</groupId>
<artifactId>minio</artifactId>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.fastjson2</groupId>
<artifactId>fastjson2</artifactId>
</dependency>
<!-- SSH -->
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>0.1.55</version>
</dependency>
<!-- Freemarker -->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<!-- Apache Axis (老项目可能需要) -->
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>org.apache.axis</groupId>
<artifactId>axis-jaxrpc</artifactId>
<version>1.4</version>
</dependency>
<!-- WSDL -->
<dependency>
<groupId>wsdl4j</groupId>
<artifactId>wsdl4j</artifactId>
<version>1.6.3</version>
</dependency>
<!-- Commons Discovery -->
<dependency>
<groupId>commons-discovery</groupId>
<artifactId>commons-discovery</artifactId>
<version>0.5</version>
</dependency>
<!-- FTP -->
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
</dependency>
<!-- Apache POI -->
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
</dependency>
<!-- 报表工具 -->
<!-- <dependency>-->
<!-- <groupId>org.jeecgframework</groupId>-->
<!-- <artifactId>autopoi-web</artifactId>-->
<!-- </dependency>-->
<!-- WebSocket -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<!-- 验证码 -->
<dependency>
<groupId>com.github.penggle</groupId>
<artifactId>kaptcha</artifactId>
</dependency>
<dependency>
<groupId>com.github.whvcse</groupId>
<artifactId>easy-captcha</artifactId>
</dependency>
<!-- 阿里云 -->
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-core</artifactId>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>aliyun-java-sdk-iot</artifactId>
</dependency>
<!-- 对象映射 -->
<dependency>
<groupId>org.modelmapper</groupId>
<artifactId>modelmapper</artifactId>
</dependency>
<!-- Sa-Token 权限认证 -->
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-spring-boot3-starter</artifactId>
</dependency>
<dependency>
<groupId>cn.dev33</groupId>
<artifactId>sa-token-redis-jackson</artifactId>
</dependency>
<!-- XXL-Job -->
<dependency>
<groupId>com.xuxueli</groupId>
<artifactId>xxl-job-core</artifactId>
</dependency>
<!-- SpringDoc OpenAPI -->
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<!-- OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- 热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- Shiro -->
<dependency>
<groupId>org.apache.shiro</groupId>
<artifactId>shiro-spring</artifactId>
</dependency>
<!-- Transmittable Thread Local -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>transmittable-thread-local</artifactId>
<version>2.14.5</version>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>io.swagger.codegen.v3</groupId>
<artifactId>swagger-codegen-maven-plugin</artifactId>
<version>3.0.71</version>
</dependency>
<dependency>
<groupId>jakarta.annotation</groupId>
<artifactId>jakarta.annotation-api</artifactId>
<version>2.1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<!-- <plugin>-->
<!-- <groupId>pl.project13.maven</groupId>-->
<!-- <artifactId>git-commit-id-plugin</artifactId>-->
<!-- </plugin>-->
</plugins>
</build>
</project>

85
templates/21.webLogAspect.java.j2

@ -0,0 +1,85 @@
package {{ package.Common }}.config;
//--- 固定引入 ---//
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RestController;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
//--- 固定引入 ---//
/***
* @Description: 日志切面
* @Author: {{author}}
* @Date: {{date}}
* @Wechat: {{ wechat }}
*/
@Slf4j
@Aspect
@Component
public class WebLogAspect {
private final ObjectMapper objectMapper = new ObjectMapper();
/** 拦截所有 Controller 方法 */
@Around("within(@org.springframework.web.bind.annotation.RestController *)")
public Object logWebRequest(ProceedingJoinPoint joinPoint) throws Throwable {
long start = System.currentTimeMillis();
ServletRequestAttributes attributes =
(ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes != null ? attributes.getRequest() : null;
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
String methodName = signature.toShortString();
// ========== 读取请求入参 ==========
String paramsJson = "";
try {
paramsJson = objectMapper.writeValueAsString(joinPoint.getArgs());
} catch (Exception ignored) {}
// ----------- 打印入参 -------
if (request != null) {
log.info("\n================= 请求开始 =================\n" +
"URL : {}\n" +
"Method : {}\n" +
"Controller : {}\n" +
"IP : {}\n" +
"Request : {}\n" +
"============================================",
request.getRequestURI(),
request.getMethod(),
methodName,
request.getRemoteAddr(),
paramsJson);
}
// ========== 执行方法 ==========
Object result = joinPoint.proceed();
// ========== 打印返回结果 ==========
String resultJson = "";
try {
resultJson = objectMapper.writeValueAsString(result);
} catch (Exception ignored) {}
log.info("\n================= 请求结束 =================\n" +
"URL : {}\n" +
"耗时 : {} ms\n" +
"返回值 : {}\n" +
"============================================",
request != null ? request.getRequestURI() : methodName,
(System.currentTimeMillis() - start),
resultJson);
return result;
}
}

0
templates/saTokenConfigure.java.j2 → templates/SaTokenConfig.java.j2

2
templates/swagger2.java.j2 → templates/SwaggerConfig.java.j2

@ -30,7 +30,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
@Configuration @Configuration
@EnableSwagger2 @EnableSwagger2
@EnableSwaggerBootstrapUI @EnableSwaggerBootstrapUI
public class Swagger2 { public class SwaggerConfig {
@Value("${swagger.show}") @Value("${swagger.show}")
private boolean swaggerShow; private boolean swaggerShow;

8
utils.py

@ -51,7 +51,7 @@ def parse_args():
) )
parser.add_argument( parser.add_argument(
"--re", "--rew",
action="store_true", action="store_true",
help="是否覆盖已存在文件(默认不覆盖)" help="是否覆盖已存在文件(默认不覆盖)"
) )
@ -63,6 +63,12 @@ def parse_args():
help="配置文件路径" help="配置文件路径"
) )
parser.add_argument(
"--jdk",
default="",
help="Java版本号"
)
return parser.parse_args() return parser.parse_args()

Loading…
Cancel
Save