From e88d24c92a5e41d7fe647e1055a502315abe3191 Mon Sep 17 00:00:00 2001 From: zhanglei Date: Mon, 9 Feb 2026 13:24:14 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0JAVA=2021=20=E7=89=88?= =?UTF-8?q?=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- generator.py | 121 ++++++-- templates/21.FilesUtil.java.j2 | 141 +++++++++ templates/21.MinioUpComponent.java.j2 | 190 ++++++++++++ templates/21.SaTokenConfig.java.j2 | 44 +++ templates/21.SwaggerConfig.java.j2 | 45 +++ templates/21.controller.java.j2 | 107 +++++++ templates/21.main.pom.xml.j2 | 283 ++++++++++++++++++ templates/21.project.pom.xml.j2 | 265 ++++++++++++++++ templates/21.webLogAspect.java.j2 | 85 ++++++ ...onfigure.java.j2 => SaTokenConfig.java.j2} | 0 ...swagger2.java.j2 => SwaggerConfig.java.j2} | 2 +- utils.py | 8 +- 12 files changed, 1259 insertions(+), 32 deletions(-) create mode 100644 templates/21.FilesUtil.java.j2 create mode 100644 templates/21.MinioUpComponent.java.j2 create mode 100644 templates/21.SaTokenConfig.java.j2 create mode 100644 templates/21.SwaggerConfig.java.j2 create mode 100644 templates/21.controller.java.j2 create mode 100644 templates/21.main.pom.xml.j2 create mode 100644 templates/21.project.pom.xml.j2 create mode 100644 templates/21.webLogAspect.java.j2 rename templates/{saTokenConfigure.java.j2 => SaTokenConfig.java.j2} (100%) rename templates/{swagger2.java.j2 => SwaggerConfig.java.j2} (98%) diff --git a/generator.py b/generator.py index 81f9acd..5d81797 100644 --- a/generator.py +++ b/generator.py @@ -1,12 +1,13 @@ import logging import os from datetime import datetime -from jinja2 import Environment, FileSystemLoader +from jinja2 import Environment, FileSystemLoader,TemplateNotFound # from config import * from db import get_table, get_columns from utils import * import argparse import yaml +import re env = Environment(loader=FileSystemLoader("templates")) @@ -24,28 +25,60 @@ def build_fields(table_name): }) 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 out_path: 输出文件路径 :param context: 渲染上下文 :param overwrite: 是否覆盖已存在文件,默认 False """ - # 文件存在且不允许覆盖 → 直接跳过 + + # 文件存在且不允许覆盖 → 跳过 if os.path.exists(out_path) and not overwrite: logging.info("Skip exists file: %s", out_path) 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) os.makedirs(os.path.dirname(out_path), exist_ok=True) with open(out_path, "w", encoding="utf-8") as f: 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 = { # "mainModule": MAIN_MODULE, @@ -119,6 +152,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove "entity.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/entity/{entity}.java", context, + java_version, over_write ) @@ -126,6 +160,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove "controller.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/controller/{entity}Controller.java", context, + java_version, over_write ) @@ -133,6 +168,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove "service.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/service/{entity}Service.java", context, + java_version, over_write ) @@ -140,6 +176,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove "serviceImpl.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/service/impl/{entity}MPJBaseServiceImpl.java", context, + java_version, over_write ) @@ -147,6 +184,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove "mapper.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/mapper/{entity}Mapper.java", context, + java_version, over_write ) @@ -154,6 +192,7 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove "mapper.xml.j2", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/mappers/{entity}Mapper.xml", context, + java_version, over_write ) @@ -162,28 +201,32 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove render( "baseEntity.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/entity/BaseEntity.java", - context + context, + java_version ) # common MybatisPlusConfig render( "mybatisPlusConfig.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/MybatisPlusConfig.java", - context + context, + java_version ) # common MybatisPlusConfig render( "webLogAspect.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/WebLogAspect.java", - context + context, + java_version ) # common 基础输出result render( "result.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/vo/Result.java", - context + context, + java_version ) #Util 公共功能 @@ -191,56 +234,64 @@ def generate(table_names: list[str], model_names: list[str], conf_name: str, ove render( file, f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/unit/{file.replace('.j2', '')}", - context + context, + java_version ) # application 启动的方法 render( "application.java.j2", f"{BASE_DIR}{MAIN_BASE_PACKAGE_DIR}/Application.java", - context + context, + java_version ) # test 测试类 render( "applicationTests.java.j2", f"{BASE_DIR}{OUTPUT_DIR}/test/{to_path(BASE_PACKAGE)}/ApplicationTests.java", - context + context, + java_version ) # 主pom文件 render( "main.pom.xml.j2", f"{BASE_DIR}{MAIN_MODULE}/pom.xml", - context + context, + java_version ) # 子项目pom文件 render( "project.pom.xml.j2", f"{BASE_DIR}{MAIN_MODULE}/{MODULE_NAME}/pom.xml", - context + context, + java_version ) #项目的yml配置文件 resources 生成环境配置为了最低限度能将项目跑起来 render( "application.yml.j2", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/application.yml", - context + context, + java_version ) #项目开发环境的yml配置文件 resources yml 只生成dev环境配置为了最低限度能将项目跑起来 render( "application-dev.yml.j2", f"{MAIN_MODULE}/{MODULE_NAME}/src/main/resources/application-dev.yml", - context + context, + java_version ) #项目开发环境的yml配置文件 resources yml 只生成dev环境配置为了最低限度能将项目跑起来 render( "logback.xml.j2", 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": # common Swagger2 render( - "swagger2.java.j2", + "SwaggerConfig.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/Swagger2.java", - context + context, + java_version ) case "saToken": # common GlobalException soToken 报错自定义 render( "globalException.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/GlobalException.java", - context + context, + java_version ) render( - "saTokenConfigure.java.j2", + "SaTokenConfig.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/SaTokenConfig.java", - context + context, + java_version ) case "minio": #MinioConfig render( "MinioConfig.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/MinioConfig.java", - context + context, + java_version ) render( "MinioUpController.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/controller/MinioUpController.java", - context + context, + java_version ) render( "MinioUpComponent.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/unit/MinioUpComponent.java", - context + context, + java_version ) case "xxlJob": # common XxlJobConfig render( "xxlJobConfig.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/config/XxlJobConfig.java", - context + context, + java_version ) # common xxjob的测试类 render( "testJob.java.j2", f"{BASE_DIR}{MAIN_OUTPUT_DIR}/common/job/TestJob.java", - context + context, + java_version ) if __name__ == "__main__": @@ -302,11 +361,13 @@ if __name__ == "__main__": tables = [t.strip() for t in args.tab.split(",") if t.strip()] models = [m.strip() for m in args.model.split(",") if m.strip()] conf = args.conf - re = args.re + version = args.jdk + rew = args.rew generate( table_names=tables, model_names=models, conf_name=conf, - over_write=re + java_version=version, + over_write=rew ) \ No newline at end of file diff --git a/templates/21.FilesUtil.java.j2 b/templates/21.FilesUtil.java.j2 new file mode 100644 index 0000000..3e6e737 --- /dev/null +++ b/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); + } + } + +} \ No newline at end of file diff --git a/templates/21.MinioUpComponent.java.j2 b/templates/21.MinioUpComponent.java.j2 new file mode 100644 index 0000000..1df9f4e --- /dev/null +++ b/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(); + } +} diff --git a/templates/21.SaTokenConfig.java.j2 b/templates/21.SaTokenConfig.java.j2 new file mode 100644 index 0000000..ad4a759 --- /dev/null +++ b/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("/**"); + } + + +} diff --git a/templates/21.SwaggerConfig.java.j2 b/templates/21.SwaggerConfig.java.j2 new file mode 100644 index 0000000..d64b800 --- /dev/null +++ b/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("") + ) + ); + } +} diff --git a/templates/21.controller.java.j2 b/templates/21.controller.java.j2 new file mode 100644 index 0000000..4a617d0 --- /dev/null +++ b/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 固定引入 ---// + +/** + *

+ * {{ table.comment }} 前端控制器 + *

+ * @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(@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 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 ids, + @RequestHeader("token") String token, + @RequestHeader(value = "version", defaultValue = "1.0") String version) { + {{table.lowerEntity}}Service.removes(ids); + return Result.OK(); + } + + +} diff --git a/templates/21.main.pom.xml.j2 b/templates/21.main.pom.xml.j2 new file mode 100644 index 0000000..2ef17bf --- /dev/null +++ b/templates/21.main.pom.xml.j2 @@ -0,0 +1,283 @@ + + + 4.0.0 + {{ groupId }} + {{ mainModule }} + 1.0.0 + ${project.artifactId} + pom + + {{ moduleName }} + + + + 3.1.10 + 2022.0.5 + UTF-8 + 21 + 21 + + + 5.8.25 + 2.0.48 + 1.2.20 + 3.5.6 + + + 8.0.33 + 42.6.0 + + + 4.1.104.Final + 8.5.7 + 4.3.1 + + + 5.2.5 + 2.11.1 + 3.10.0 + + + 1.13.0 + 1.38.0 + 2.2.0 + + + 3.11.0 + + + + + + aliyun + Aliyun Maven + https://maven.aliyun.com/repository/public + + true + + + false + + + + spring-milestones + Spring Milestones + https://repo.spring.io/milestone + + + jitpack.io + JitPack Repository + https://jitpack.io + + + + + + + + org.springframework.boot + spring-boot-dependencies + ${spring-boot.version} + pom + import + + + + + org.springframework.cloud + spring-cloud-dependencies + ${spring-cloud.version} + pom + import + + + + + cn.hutool + hutool-all + ${hutool.version} + + + + com.alibaba.fastjson2 + fastjson2 + ${fastjson2.version} + + + + com.alibaba + druid-spring-boot-3-starter + ${druid.version} + + + + com.baomidou + mybatis-plus-spring-boot3-starter + ${mybatisplus.version} + + + + mysql + mysql-connector-java + ${mysql.version} + + + + io.netty + netty-all + ${netty.version} + + + + io.minio + minio + ${minio.version} + + + + org.apache.poi + poi + ${poi.version} + + + + org.apache.poi + poi-ooxml + ${poi.version} + + + + org.apache.commons + commons-pool2 + ${commons-pool2.version} + + + + commons-net + commons-net + ${commons-net.version} + + + + org.apache.shiro + shiro-spring + ${shiro.version} + + + + cn.dev33 + sa-token-spring-boot3-starter + ${sa-token.version} + + + + cn.dev33 + sa-token-redis-jackson + ${sa-token.version} + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + ${springdoc.version} + + + + com.github.penggle + kaptcha + 2.3.2 + + + + com.aliyun + aliyun-java-sdk-core + 4.6.4 + + + + com.aliyun + aliyun-java-sdk-iot + 7.7.0 + + + + com.github.yulichang + mybatis-plus-join-boot-starter + 1.4.13 + + + + com.github.yulichang + mybatis-plus-join-core + 1.4.13 + + + + com.xuxueli + xxl-job-core + 2.4.1 + + + + org.modelmapper + modelmapper + 3.2.0 + + + + com.github.whvcse + easy-captcha + 1.6.2 + + + + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-test + test + + + + org.projectlombok + lombok + provided + + + + + + + + org.springframework.boot + spring-boot-maven-plugin + ${spring-boot.version} + + + + maven-compiler-plugin + ${maven-compiler-plugin.version} + + ${java.version} + ${project.build.sourceEncoding} + + + + + + + + + maven-compiler-plugin + + + + \ No newline at end of file diff --git a/templates/21.project.pom.xml.j2 b/templates/21.project.pom.xml.j2 new file mode 100644 index 0000000..5ca52ac --- /dev/null +++ b/templates/21.project.pom.xml.j2 @@ -0,0 +1,265 @@ + + + 4.0.0 + + {{ groupId }} + {{ mainModule }} + 1.0.0 + + + {{ moduleName }} + {{ moduleName }} + + + + + org.springframework.boot + spring-boot-starter-web + + + + org.springframework.boot + spring-boot-starter-jdbc + + + + + mysql + mysql-connector-java + + + + com.alibaba + druid-spring-boot-3-starter + + + + + com.baomidou + mybatis-plus-spring-boot3-starter + + + + + + + + + + com.github.yulichang + mybatis-plus-join-boot-starter + + + + + org.springframework.boot + spring-boot-starter-data-redis + + + + org.apache.commons + commons-pool2 + + + + + io.netty + netty-all + + + + + io.minio + minio + + + + + cn.hutool + hutool-all + + + + com.alibaba.fastjson2 + fastjson2 + + + + + com.jcraft + jsch + 0.1.55 + + + + + org.freemarker + freemarker + + + + + org.apache.axis + axis + 1.4 + + + + org.apache.axis + axis-jaxrpc + 1.4 + + + + + wsdl4j + wsdl4j + 1.6.3 + + + + + commons-discovery + commons-discovery + 0.5 + + + + + commons-net + commons-net + + + + + org.apache.poi + poi + + + + org.apache.poi + poi-ooxml + + + + + + + + + + + org.springframework.boot + spring-boot-starter-websocket + + + + + com.github.penggle + kaptcha + + + + com.github.whvcse + easy-captcha + + + + + com.aliyun + aliyun-java-sdk-core + + + + com.aliyun + aliyun-java-sdk-iot + + + + + org.modelmapper + modelmapper + + + + + cn.dev33 + sa-token-spring-boot3-starter + + + + cn.dev33 + sa-token-redis-jackson + + + + + com.xuxueli + xxl-job-core + + + + + org.springdoc + springdoc-openapi-starter-webmvc-ui + + + + + org.springframework.cloud + spring-cloud-starter-openfeign + + + + + org.springframework.boot + spring-boot-devtools + true + + + + + org.apache.shiro + shiro-spring + + + + + com.alibaba + transmittable-thread-local + 2.14.5 + + + + + org.projectlombok + lombok + + + + io.swagger.codegen.v3 + swagger-codegen-maven-plugin + 3.0.71 + + + jakarta.annotation + jakarta.annotation-api + 2.1.1 + + + + + + + org.springframework.boot + spring-boot-maven-plugin + + + + + + + + + \ No newline at end of file diff --git a/templates/21.webLogAspect.java.j2 b/templates/21.webLogAspect.java.j2 new file mode 100644 index 0000000..64deb75 --- /dev/null +++ b/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; + } +} diff --git a/templates/saTokenConfigure.java.j2 b/templates/SaTokenConfig.java.j2 similarity index 100% rename from templates/saTokenConfigure.java.j2 rename to templates/SaTokenConfig.java.j2 diff --git a/templates/swagger2.java.j2 b/templates/SwaggerConfig.java.j2 similarity index 98% rename from templates/swagger2.java.j2 rename to templates/SwaggerConfig.java.j2 index da9debd..636e987 100644 --- a/templates/swagger2.java.j2 +++ b/templates/SwaggerConfig.java.j2 @@ -30,7 +30,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2; @Configuration @EnableSwagger2 @EnableSwaggerBootstrapUI -public class Swagger2 { +public class SwaggerConfig { @Value("${swagger.show}") private boolean swaggerShow; diff --git a/utils.py b/utils.py index cda26ec..a29c556 100644 --- a/utils.py +++ b/utils.py @@ -51,7 +51,7 @@ def parse_args(): ) parser.add_argument( - "--re", + "--rew", action="store_true", help="是否覆盖已存在文件(默认不覆盖)" ) @@ -63,6 +63,12 @@ def parse_args(): help="配置文件路径" ) + parser.add_argument( + "--jdk", + default="", + help="Java版本号" + ) + return parser.parse_args()