代码生成器 模板仓库 模板预览

This commit is contained in:
cuijiawang 2025-09-27 16:03:47 +08:00
parent d6be017f37
commit 5d19f5589a
4 changed files with 248 additions and 0 deletions

View File

@ -1,6 +1,7 @@
package com.agileboot.codegen.controller;
import com.agileboot.codegen.dto.CodegenRequest;
import com.agileboot.codegen.dto.TemplatePreviewRequest;
import com.agileboot.codegen.service.IGeneratorService;
import com.agileboot.codegen.service.ITemplateRepositoryService;
import com.agileboot.codegen.service.ITemplateUsageLogService;
@ -103,4 +104,95 @@ public class GeneratorController {
return R.fail("生成代码失败: " + e.getMessage());
}
}
@GetMapping("/template/preview")
public R<?> previewTemplateGet(@RequestParam("templateSource") String templateSource,
@RequestParam("templateId") String templateId,
@RequestParam(value = "tableSql", required = false) String tableSql,
@RequestParam(value = "templateContent", required = false) String templateContent,
@RequestParam(value = "authorName", required = false) String authorName) {
try {
log.info("开始预览模板(GET),模板来源: {}, 模板ID: {}", templateSource, templateId);
// 参数验证
if (templateSource == null || templateId == null) {
return R.fail("模板来源和模板ID不能为空");
}
// 如果没有提供tableSql使用默认的示例SQL
if (tableSql == null || tableSql.trim().isEmpty()) {
tableSql = "CREATE TABLE `user` (\n" +
" `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',\n" +
" `username` varchar(50) NOT NULL COMMENT '用户名',\n" +
" `password` varchar(100) NOT NULL COMMENT '密码',\n" +
" `email` varchar(100) DEFAULT NULL COMMENT '邮箱',\n" +
" `phone` varchar(20) DEFAULT NULL COMMENT '手机号',\n" +
" `status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态(0-禁用 1-启用)',\n" +
" `create_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',\n" +
" `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',\n" +
" PRIMARY KEY (`id`),\n" +
" UNIQUE KEY `uk_username` (`username`)\n" +
") ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表';";
log.info("使用默认示例SQL进行模板预览");
}
// 构建选项参数
Map<String, Object> options = new HashMap<>();
options.put("tableSql", tableSql);
if (authorName != null && !authorName.trim().isEmpty()) {
options.put("authorName", authorName);
}
// 调用生成服务预览单个模板
String previewResult = generatorService.previewSingleTemplate(
templateSource,
templateId,
templateContent,
options);
log.info("模板预览完成(GET),模板来源: {}, 模板ID: {}", templateSource, templateId);
return R.ok("预览成功", previewResult);
} catch (Exception e) {
log.error("预览模板失败(GET)", e);
return R.fail("预览模板失败: " + e.getMessage());
}
}
@PostMapping("/template/preview")
public R<?> previewTemplate(@RequestBody TemplatePreviewRequest request) {
try {
log.info("开始预览模板,模板来源: {}, 模板ID: {}", request.getTemplateSource(), request.getTemplateId());
// 参数验证
if (request.getTemplateSource() == null || request.getTemplateId() == null) {
return R.fail("模板来源和模板ID不能为空");
}
if (request.getTableSql() == null || request.getTableSql().trim().isEmpty()) {
return R.fail("表SQL语句不能为空");
}
// 合并请求参数
Map<String, Object> options = new HashMap<>();
if (request.getOptions() != null) {
options.putAll(request.getOptions());
}
options.put("tableSql", request.getTableSql());
// 调用生成服务预览单个模板
String previewResult = generatorService.previewSingleTemplate(
request.getTemplateSource(),
request.getTemplateId(),
request.getTemplateContent(),
options);
log.info("模板预览完成,模板来源: {}, 模板ID: {}", request.getTemplateSource(), request.getTemplateId());
return R.ok("预览成功", previewResult);
} catch (Exception e) {
log.error("预览模板失败", e);
return R.fail("预览模板失败: " + e.getMessage());
}
}
}

View File

@ -0,0 +1,40 @@
package com.agileboot.codegen.dto;
import lombok.Data;
import java.util.Map;
/**
* 模板预览请求DTO
*
* @author system
* @date 2025-09-27
*/
@Data
public class TemplatePreviewRequest {
/**
* 模板来源(system-系统模板, user-用户模板)
*/
private String templateSource;
/**
* 模板ID
*/
private String templateId;
/**
* 表SQL语句
*/
private String tableSql;
/**
* 生成选项
*/
private Map<String, Object> options;
/**
* 模板内容(当templateSource为content时使用)
*/
private String templateContent;
}

View File

@ -141,4 +141,109 @@ public class GeneratorServiceImpl implements IGeneratorService {
return "// 生成失败: " + e.getMessage();
}
}
@Override
public String previewSingleTemplate(String templateSource, String templateId, String templateContent, Map<String, Object> options) {
try {
// 1. 解析SQL获取表结构信息
String tableSql = MapUtil.getString(options, "tableSql");
String ignorePrefix = MapUtil.getString(options, "ignorePrefix", "");
if (StringUtils.isBlank(tableSql)) {
log.error("SQL语句为空");
return "// 错误: SQL语句不能为空";
}
ClassInfo classInfo = TableParseUtil.parseTableSql(tableSql, ignorePrefix);
if (classInfo == null) {
log.error("解析SQL失败");
return "// 错误: 解析SQL失败";
}
// 2. 设置生成参数
options.put("classInfo", classInfo);
options.put("tableName", classInfo.getTableName());
options.put("authorName", MapUtil.getString(options, "authorName", "Wol"));
// 3. 根据模板来源生成代码
String generatedCode;
switch (templateSource.toLowerCase()) {
case "user":
// 用户自定义模板从数据库获取模板内容
UserTemplate userTemplate = userTemplateMapper.selectById(Long.valueOf(templateId));
if (userTemplate != null && StringUtils.isNotBlank(userTemplate.getTemplateContent())) {
generatedCode = FreemarkerUtil.generateByContent(userTemplate.getTemplateContent(), options);
} else {
log.warn("用户模板不存在或内容为空: templateId={}", templateId);
generatedCode = "// 用户模板不存在或内容为空: " + templateId;
}
break;
case "system":
// 系统模板需要根据templateId查找对应的模板文件
generatedCode = generateSystemTemplate(templateId, options);
break;
case "content":
// 直接使用提供的模板内容
if (StringUtils.isNotBlank(templateContent)) {
generatedCode = FreemarkerUtil.generateByContent(templateContent, options);
} else {
generatedCode = "// 错误: 模板内容为空";
}
break;
default:
generatedCode = "// 错误: 不支持的模板来源: " + templateSource;
break;
}
return generatedCode;
} catch (Exception e) {
log.error("预览模板失败: templateSource={}, templateId={}", templateSource, templateId, e);
return "// 预览失败: " + e.getMessage();
}
}
/**
* 生成系统模板代码
*/
private String generateSystemTemplate(String templateId, Map<String, Object> options) {
try {
// 从系统模板配置中查找对应的模板信息
String templateConfig = getTemplateConfig();
JSONArray templateGroups = JSONArray.parseArray(templateConfig);
for (Object groupObj : templateGroups) {
JSONObject group = (JSONObject) groupObj;
String groupName = group.getString("group");
JSONArray templates = group.getJSONArray("templates");
for (Object templateObj : templates) {
JSONObject template = (JSONObject) templateObj;
String id = template.getString("id");
String name = template.getString("name");
if (templateId.equals(id)) {
// 找到对应的模板生成代码
String templatePath = groupName + "/" + name + ".ftl";
if (FreemarkerUtil.templateExists(templatePath)) {
return FreemarkerUtil.generateByTemplate(templatePath, options);
} else {
log.warn("系统模板文件不存在: {}", templatePath);
return "// 系统模板文件不存在: " + templatePath;
}
}
}
}
return "// 系统模板不存在: " + templateId;
} catch (Exception e) {
log.error("生成系统模板失败: templateId={}", templateId, e);
return "// 生成系统模板失败: " + e.getMessage();
}
}
}

View File

@ -25,4 +25,15 @@ public interface IGeneratorService {
* @return 生成的代码Map
*/
Map<String, String> getResultByParams(Map<String, Object> options, String templateConfig);
/**
* 预览单个模板
*
* @param templateSource 模板来源(system/user/content)
* @param templateId 模板ID
* @param templateContent 模板内容(当templateSource为content时使用)
* @param options 生成参数
* @return 生成的代码内容
*/
String previewSingleTemplate(String templateSource, String templateId, String templateContent, Map<String, Object> options);
}