init
This commit is contained in:
parent
ce7a7e2c00
commit
09a9767992
186
MainFrame.java
186
MainFrame.java
@ -1,186 +0,0 @@
|
||||
// 创建代码生成配置面板
|
||||
private JPanel createGeneratorPanel() {
|
||||
JPanel panel = new JPanel(new BorderLayout(10, 10));
|
||||
panel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
|
||||
|
||||
// 标题
|
||||
JLabel titleLabel = new JLabel("代码生成配置");
|
||||
titleLabel.setFont(new Font("微软雅黑", Font.BOLD, 18));
|
||||
titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 20, 0));
|
||||
panel.add(titleLabel, BorderLayout.NORTH);
|
||||
|
||||
// 主内容面板,分为上下两部分
|
||||
JPanel contentPanel = new JPanel(new BorderLayout(10, 10));
|
||||
|
||||
// 上部分:配置选项
|
||||
JPanel configPanel = new JPanel(new GridBagLayout());
|
||||
GridBagConstraints gbc = new GridBagConstraints();
|
||||
gbc.insets = new Insets(5, 5, 5, 5);
|
||||
gbc.anchor = GridBagConstraints.WEST;
|
||||
|
||||
// 基础包名
|
||||
JLabel basePackageLabel = new JLabel("基础包名:");
|
||||
basePackageField = new JTextField();
|
||||
basePackageField.setPreferredSize(new Dimension(300, 25));
|
||||
|
||||
// 是否启用Lombok
|
||||
JLabel lombokLabel = new JLabel("启用Lombok:");
|
||||
lombokCheckBox = new JCheckBox();
|
||||
lombokCheckBox.setSelected(true);
|
||||
|
||||
// 父类实体
|
||||
JLabel superEntityLabel = new JLabel("父类实体:");
|
||||
superEntityField = new JTextField();
|
||||
superEntityField.setPreferredSize(new Dimension(300, 25));
|
||||
|
||||
// 父类公共字段
|
||||
JLabel superColumnsLabel = new JLabel("父类公共字段:");
|
||||
superColumnsField = new JTextField();
|
||||
superColumnsField.setPreferredSize(new Dimension(300, 25));
|
||||
superColumnsField.setToolTipText("多个字段用逗号分隔,如:id,createTime,updateTime");
|
||||
|
||||
// Vue2 生成选项
|
||||
JLabel generateVue2Label = new JLabel("生成Vue2代码:");
|
||||
generateVue2CheckBox = new JCheckBox();
|
||||
generateVue2CheckBox.setSelected(true);
|
||||
|
||||
// Vue3 生成选项
|
||||
JLabel generateVue3Label = new JLabel("生成Vue3代码:");
|
||||
generateVue3CheckBox = new JCheckBox();
|
||||
generateVue3CheckBox.setSelected(true);
|
||||
|
||||
// 保存配置按钮
|
||||
JButton saveConfigBtn = new JButton("保存配置");
|
||||
saveConfigBtn.addActionListener(e -> saveGeneratorConfig());
|
||||
|
||||
// 添加组件到配置面板
|
||||
int row = 0;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
configPanel.add(basePackageLabel, gbc);
|
||||
gbc.gridx = 1;
|
||||
configPanel.add(basePackageField, gbc);
|
||||
|
||||
row++;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
configPanel.add(lombokLabel, gbc);
|
||||
gbc.gridx = 1;
|
||||
configPanel.add(lombokCheckBox, gbc);
|
||||
|
||||
row++;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
configPanel.add(superEntityLabel, gbc);
|
||||
gbc.gridx = 1;
|
||||
configPanel.add(superEntityField, gbc);
|
||||
|
||||
row++;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
configPanel.add(superColumnsLabel, gbc);
|
||||
gbc.gridx = 1;
|
||||
configPanel.add(superColumnsField, gbc);
|
||||
|
||||
row++;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
configPanel.add(generateVue2Label, gbc);
|
||||
gbc.gridx = 1;
|
||||
configPanel.add(generateVue2CheckBox, gbc);
|
||||
|
||||
row++;
|
||||
gbc.gridx = 0;
|
||||
gbc.gridy = row;
|
||||
configPanel.add(generateVue3Label, gbc);
|
||||
gbc.gridx = 1;
|
||||
configPanel.add(generateVue3CheckBox, gbc);
|
||||
|
||||
row++;
|
||||
gbc.gridx = 1;
|
||||
gbc.gridy = row + 1;
|
||||
gbc.anchor = GridBagConstraints.EAST;
|
||||
configPanel.add(saveConfigBtn, gbc);
|
||||
|
||||
contentPanel.add(configPanel, BorderLayout.NORTH);
|
||||
|
||||
// 下部分:表选择
|
||||
JPanel tablePanel = new JPanel(new BorderLayout(10, 10));
|
||||
// 过滤面板
|
||||
JPanel filterPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||
JLabel filterLabel = new JLabel("过滤:");
|
||||
tableFilterField = new JTextField(20);
|
||||
JButton filterBtn = new JButton("查询");
|
||||
|
||||
filterBtn.addActionListener(e -> filterTables());
|
||||
|
||||
filterPanel.add(filterLabel);
|
||||
filterPanel.add(tableFilterField);
|
||||
filterPanel.add(filterBtn);
|
||||
|
||||
tablePanel.add(filterPanel, BorderLayout.NORTH);
|
||||
|
||||
// 表列表
|
||||
String[] columnNames = {"选择", "表名"};
|
||||
tableModel = new DefaultTableModel(columnNames, 0) {
|
||||
@Override
|
||||
public Class<?> getColumnClass(int column) {
|
||||
return column == 0 ? Boolean.class : String.class;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isCellEditable(int row, int column) {
|
||||
return column == 0;
|
||||
}
|
||||
};
|
||||
|
||||
tableTable = new JTable(tableModel);
|
||||
tableTable.getColumnModel().getColumn(0).setPreferredWidth(50);
|
||||
tableTable.getColumnModel().getColumn(1).setPreferredWidth(300);
|
||||
tableTable.addMouseListener(new MouseAdapter() {
|
||||
@Override
|
||||
public void mouseClicked(MouseEvent e) {
|
||||
int column = tableTable.columnAtPoint(e.getPoint());
|
||||
int row = tableTable.rowAtPoint(e.getPoint());
|
||||
if (row != -1) {
|
||||
if (column == 0) {
|
||||
// 点击复选框列,切换选中状态
|
||||
Boolean checked = (Boolean) tableTable.getValueAt(row, 0);
|
||||
tableTable.setValueAt(!checked, row, 0);
|
||||
} else {
|
||||
// 点击其他列,也切换选中状态
|
||||
Boolean checked = (Boolean) tableTable.getValueAt(row, 0);
|
||||
tableTable.setValueAt(!checked, row, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
JScrollPane tableScrollPane = new JScrollPane(tableTable);
|
||||
tablePanel.add(tableScrollPane, BorderLayout.CENTER);
|
||||
|
||||
contentPanel.add(tablePanel, BorderLayout.CENTER);
|
||||
|
||||
panel.add(contentPanel, BorderLayout.CENTER);
|
||||
|
||||
// 按钮面板
|
||||
JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
|
||||
JButton backBtn = new JButton("返回");
|
||||
JButton generateBtn = new JButton("生成代码");
|
||||
|
||||
backBtn.addActionListener(e -> {
|
||||
CardLayout cl = (CardLayout) ((JPanel) getContentPane().getComponent(0)).getLayout();
|
||||
cl.show((JPanel) getContentPane().getComponent(0), "dbPanel");
|
||||
});
|
||||
|
||||
generateBtn.addActionListener(e -> generateCode());
|
||||
|
||||
buttonPanel.add(backBtn);
|
||||
buttonPanel.add(generateBtn);
|
||||
panel.add(buttonPanel, BorderLayout.SOUTH);
|
||||
|
||||
// 加载已保存的配置
|
||||
loadGeneratorConfig();
|
||||
|
||||
return panel;
|
||||
}
|
||||
439
foo.java
439
foo.java
@ -1,439 +0,0 @@
|
||||
public class BackendCodeGenerator {
|
||||
// 生成后端代码
|
||||
public static void generateBackendCode(String url, String username, String password, List<String> tables, Map<String, Map<String,Object>> columns) {
|
||||
GeneratorConfig generatorConfig = ConfigUtil.getGeneratorConfigAsObject();
|
||||
String basePackage = generatorConfig.getBasePackage();
|
||||
String superEntityClass = generatorConfig.getSuperEntityClass();
|
||||
String[] superEntityColumns = generatorConfig.getSuperEntityColumns();
|
||||
|
||||
// 解析包名,获取作者和模块名
|
||||
String author = System.getProperty("user.name");
|
||||
String moduleName = basePackage.substring(basePackage.lastIndexOf(".") + 1);
|
||||
|
||||
// 生成路径
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
String outputDir = projectPath + "/generated-code/backend/src/main/java";
|
||||
|
||||
FastAutoGenerator.create(url, username, password)
|
||||
// 全局配置
|
||||
.globalConfig(builder -> {
|
||||
builder.author(author) // 设置作者
|
||||
.enableSwagger() // 开启Swagger模式
|
||||
.outputDir(outputDir) // 指定输出目录
|
||||
.dateType(DateType.ONLY_DATE); // 时间策略
|
||||
})
|
||||
// 包配置
|
||||
.packageConfig(builder -> {
|
||||
builder.parent(basePackage) // 父包名
|
||||
.moduleName(moduleName) // 父包模块名
|
||||
// 模块名为seer
|
||||
// 实体类包名为entity
|
||||
.entity("entity")
|
||||
// 服务层包名为service
|
||||
.service("service")
|
||||
// 服务实现类包名为service.impl
|
||||
.serviceImpl("service.impl")
|
||||
// Mapper接口包名为mapper
|
||||
.mapper("mapper")
|
||||
// Mapper XML文件包名为mapper.xml
|
||||
.xml("mapper.xml")
|
||||
// 构建包配置
|
||||
.pathInfo(Collections.singletonMap(OutputFile.xml,
|
||||
projectPath + "/generated-code/backend/src/main/resources/mapper"));
|
||||
})
|
||||
// 策略配置
|
||||
.strategyConfig(builder -> {
|
||||
builder.addInclude(tables) // 设置需要生成的表名
|
||||
.addTablePrefix("t_", "sys_") // 设置过滤表前缀
|
||||
|
||||
// Entity策略配置
|
||||
.entityBuilder()
|
||||
.enableLombok() // 开启Lombok
|
||||
.superClass(superEntityClass) // 设置父类
|
||||
.addSuperEntityColumns(superEntityColumns) // 父类公共字段
|
||||
.enableTableFieldAnnotation() // 开启字段注解
|
||||
// Service策略配置
|
||||
.serviceBuilder()
|
||||
.formatServiceFileName("I%sService")
|
||||
.formatServiceImplFileName("%sServiceImpl")
|
||||
// Mapper策略配置
|
||||
.mapperBuilder()
|
||||
.superClass(BaseMapper.class) // 设置父类
|
||||
.enableMapperAnnotation() // 开启@Mapper注解
|
||||
.formatMapperFileName("%sMapper")
|
||||
.formatXmlFileName("%sMapper");
|
||||
|
||||
builder.entityBuilder()
|
||||
// 实体类继承自BaseEntity类
|
||||
.superClass(BaseEntity.class)
|
||||
// 启用Lombok注解
|
||||
.enableLombok()
|
||||
// 启用表字段注解
|
||||
.enableTableFieldAnnotation()
|
||||
// 逻辑删除字段名为deleted
|
||||
.logicDeleteColumnName("deleted")
|
||||
// 添加父类实体的共有字段
|
||||
.addSuperEntityColumns("id", "created_by", "created_time", "updated_by", "updated_time")
|
||||
// 添加表字段填充策略
|
||||
.addTableFills(new Column("create_time", FieldFill.INSERT))
|
||||
// 添加属性填充策略
|
||||
.addTableFills(new Property("update_time", FieldFill.INSERT_UPDATE))
|
||||
// 主键类型为AUTO
|
||||
.idType(IdType.AUTO)
|
||||
// 设置生成文件名格式为%sEntity
|
||||
.formatFileName("%sEntity")
|
||||
// 构建实体类配置
|
||||
.build();
|
||||
})
|
||||
// 使用Freemarker引擎模板
|
||||
.templateEngine(new FreemarkerTemplateEngine())
|
||||
.execute();
|
||||
|
||||
// 生成自定义Controller
|
||||
generateControllers(basePackage, moduleName, tables);
|
||||
|
||||
// 生成请求和响应类
|
||||
generateRequestAndResponseClasses(basePackage, tables,columns);
|
||||
}
|
||||
|
||||
// 生成符合RESTful规范的Controller
|
||||
private static void generateControllers(String basePackage, String moduleName, List<String> tables) {
|
||||
try {
|
||||
// 初始化FreeMarker配置
|
||||
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
|
||||
cfg.setClassForTemplateLoading(BackendCodeGenerator.class, "/templates/backend");
|
||||
cfg.setDefaultEncoding("UTF-8");
|
||||
|
||||
// 获取模板
|
||||
Template template = cfg.getTemplate("custom-controller.java.ftl");
|
||||
|
||||
// 生成路径
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
String outputDir = projectPath + "/generated-code/backend/src/main/java/" +
|
||||
basePackage.replace(".", "/") + "/" + moduleName + "/controller/";
|
||||
|
||||
// 创建目录
|
||||
File dir = new File(outputDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
// 为每个表生成Controller
|
||||
for (String table : tables) {
|
||||
// 处理表名,转换为类名
|
||||
String className = tableToClassName(table);
|
||||
String varName = className.substring(0, 1).toLowerCase() + className.substring(1);
|
||||
|
||||
// 准备数据模型
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
dataModel.put("basePackage", basePackage);
|
||||
dataModel.put("moduleName", moduleName);
|
||||
dataModel.put("className", className);
|
||||
dataModel.put("varName", varName);
|
||||
dataModel.put("author", System.getProperty("user.name"));
|
||||
dataModel.put("date", new Date());
|
||||
|
||||
// 生成文件
|
||||
String fileName = outputDir + className + "Controller.java";
|
||||
try (Writer out = new FileWriter(new File(fileName))) {
|
||||
template.process(dataModel, out);
|
||||
}
|
||||
}
|
||||
} catch (IOException | TemplateException e) {
|
||||
log.info("生成Controller文件失败:" + e.getMessage(),e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成所有请求和响应类
|
||||
*/
|
||||
public static void generateRequestAndResponseClasses(String basePackage, List<String> tables, Map<String, Map<String,Object>> columns) {
|
||||
List<String> commonColumns = Arrays.asList("deleted","createTime","updateTime","createBy","updateBy");
|
||||
Map<String, Map<String,Object>> columnMaps = columns.entrySet().stream().filter(entry -> !commonColumns.contains(entry.getKey())).collect(Collectors.toMap(p -> p.getKey(), p -> p.getValue()));
|
||||
|
||||
// 生成响应类
|
||||
generateResponseClasses(basePackage, tables,columnMaps);
|
||||
|
||||
// 生成查询请求类
|
||||
generateQueryRequestClasses(basePackage, tables,columnMaps);
|
||||
|
||||
// 生成通用请求类
|
||||
generateRequestClasses(basePackage, tables,columnMaps);
|
||||
|
||||
// 生成PageRequest基类
|
||||
generatePageRequestClass(basePackage, tables,columnMaps);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成统一响应类
|
||||
*/
|
||||
public static void generateResponseClasses(String basePackage, List<String> tables, Map<String, Map<String,Object>> tableColumnsInfo) {
|
||||
generateClassFiles(basePackage, tables, tableColumnsInfo, "admin-response.java.ftl", "Response", "/controller/response/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成查询请求类
|
||||
*/
|
||||
public static void generateQueryRequestClasses(String basePackage, List<String> tables, Map<String, Map<String,Object>> tableColumnsInfo) {
|
||||
generateClassFiles(basePackage, tables, tableColumnsInfo, "admin-query-admin-request.java.ftl", "QueryRequest", "/controller/request/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成通用请求类
|
||||
*/
|
||||
public static void generateRequestClasses(String basePackage, List<String> tables, Map<String, Map<String,Object>> tableColumnsInfo) {
|
||||
generateClassFiles(basePackage, tables, tableColumnsInfo, "admin-request.java.ftl", "Request", "/controller/request/");
|
||||
}
|
||||
|
||||
/**
|
||||
* 通用类文件生成方法
|
||||
*/
|
||||
private static void generateClassFiles(String basePackage, List<String> tables, Map<String, Map<String,Object>> tableColumnsInfo,
|
||||
String templateName, String suffix, String outputPath) {
|
||||
try {
|
||||
// 初始化FreeMarker配置
|
||||
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
|
||||
cfg.setClassForTemplateLoading(BackendCodeGenerator.class, "/templates/backend");
|
||||
cfg.setDefaultEncoding("UTF-8");
|
||||
|
||||
// 获取模板
|
||||
Template template = cfg.getTemplate(templateName);
|
||||
|
||||
// 生成路径
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
String outputDir = projectPath + "/generated-code/backend/src/main/java/" +
|
||||
basePackage.replace(".", "/") + outputPath;
|
||||
|
||||
// 创建目录
|
||||
File dir = new File(outputDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
// 为每个表生成类文件
|
||||
for (String table : tables) {
|
||||
// 处理表名,转换为类名
|
||||
String className = tableToClassName(table);
|
||||
|
||||
// 获取表的列信息
|
||||
Map<String, Object> tableInfo = tableColumnsInfo.get(table);
|
||||
List<ColumnInfo> columns = new ArrayList<>();
|
||||
boolean hasDateField = false;
|
||||
boolean hasBigDecimalField = false;
|
||||
|
||||
if (tableInfo != null) {
|
||||
columns = processColumns(tableInfo);
|
||||
hasDateField = hasFieldType(columns, "Date");
|
||||
hasBigDecimalField = hasFieldType(columns, "BigDecimal");
|
||||
}
|
||||
|
||||
// 准备数据模型
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
dataModel.put("basePackage", basePackage);
|
||||
dataModel.put("className", className);
|
||||
dataModel.put("columns", columns);
|
||||
dataModel.put("hasDateField", hasDateField);
|
||||
dataModel.put("hasBigDecimalField", hasBigDecimalField);
|
||||
|
||||
// 生成文件
|
||||
String fileName = outputDir + className + suffix + ".java";
|
||||
try (Writer out = new FileWriter(new File(fileName))) {
|
||||
template.process(dataModel, out);
|
||||
}
|
||||
}
|
||||
} catch (IOException | TemplateException e) {
|
||||
log.error("生成" + suffix + "类文件失败:" + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成PageRequest基类
|
||||
*/
|
||||
public static void generatePageRequestClass(String basePackage, List<String> tables, Map<String, Map<String,Object>> columns) {
|
||||
try {
|
||||
// 初始化FreeMarker配置
|
||||
Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
|
||||
cfg.setClassForTemplateLoading(BackendCodeGenerator.class, "/templates/backend");
|
||||
cfg.setDefaultEncoding("UTF-8");
|
||||
|
||||
Template pageRequestTemplate = cfg.getTemplate("admin-pageRequest.java.ftl");
|
||||
// 生成路径
|
||||
String projectPath = System.getProperty("user.dir");
|
||||
String outputDir = projectPath + "/generated-code/backend/src/main/java/" +
|
||||
basePackage.replace(".", "/") + "/controller/request/";
|
||||
|
||||
// 创建目录
|
||||
File dir = new File(outputDir);
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
|
||||
// 为每个表生成Controller
|
||||
for (String table : tables) {
|
||||
// 处理表名,转换为类名
|
||||
String className = tableToClassName(table);
|
||||
String varName = className.substring(0, 1).toLowerCase() + className.substring(1);
|
||||
|
||||
// 准备数据模型
|
||||
Map<String, Object> dataModel = new HashMap<>();
|
||||
dataModel.put("basePackage", basePackage);
|
||||
dataModel.put("className", className);
|
||||
dataModel.put("varName", varName);
|
||||
dataModel.put("author", System.getProperty("user.name"));
|
||||
dataModel.put("date", new Date());
|
||||
|
||||
// 生成文件
|
||||
String fileName = outputDir + className + "Controller.java";
|
||||
try (Writer out = new FileWriter(new File(fileName))) {
|
||||
pageRequestTemplate.process(dataModel, out);
|
||||
}
|
||||
}
|
||||
} catch (IOException | TemplateException e) {
|
||||
log.error("生成PageRequest基类文件失败:" + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
|
||||
// 表名转类名(下划线转驼峰)
|
||||
private static String tableToClassName(String tableName) {
|
||||
// 去除表前缀
|
||||
if (tableName.startsWith("t_")) {
|
||||
tableName = tableName.substring(2);
|
||||
}
|
||||
|
||||
// 下划线转驼峰
|
||||
StringBuilder sb = new StringBuilder();
|
||||
boolean nextUpperCase = false;
|
||||
for (char c : tableName.toCharArray()) {
|
||||
if (c == '_') {
|
||||
nextUpperCase = true;
|
||||
} else {
|
||||
if (nextUpperCase) {
|
||||
sb.append(Character.toUpperCase(c));
|
||||
nextUpperCase = false;
|
||||
} else {
|
||||
sb.append(c);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 首字母大写
|
||||
if (sb.length() > 0) {
|
||||
sb.setCharAt(0, Character.toUpperCase(sb.charAt(0)));
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理列信息,转换为Java属性
|
||||
*/
|
||||
private static List<ColumnInfo> processColumns(Map<String, Object> tableInfo) {
|
||||
List<ColumnInfo> columnInfos = new ArrayList<>();
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Map<String, Object>> columns = (List<Map<String, Object>>) tableInfo.get("columns");
|
||||
|
||||
if (columns != null) {
|
||||
for (Map<String, Object> column : columns) {
|
||||
ColumnInfo info = new ColumnInfo();
|
||||
|
||||
String columnName = (String) column.get("columnName");
|
||||
String dataType = (String) column.get("dataType");
|
||||
String columnComment = (String) column.get("columnComment");
|
||||
String isNullable = (String) column.get("isNullable");
|
||||
String columnKey = (String) column.get("columnKey");
|
||||
|
||||
info.setColumnName(columnName);
|
||||
info.setPropertyName(columnToProperty(columnName));
|
||||
info.setJavaType(mapDataTypeToJavaType(dataType));
|
||||
info.setDataType(dataType);
|
||||
info.setComment(columnComment != null ? columnComment : "");
|
||||
info.setNullable("YES".equalsIgnoreCase(isNullable));
|
||||
info.setPrimaryKey("PRI".equalsIgnoreCase(columnKey));
|
||||
|
||||
columnInfos.add(info);
|
||||
}
|
||||
}
|
||||
|
||||
return columnInfos;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据库列名转换为Java属性名(下划线转驼峰)
|
||||
*/
|
||||
private static String columnToProperty(String columnName) {
|
||||
if (columnName == null || columnName.isEmpty()) {
|
||||
return columnName;
|
||||
}
|
||||
|
||||
StringBuilder result = new StringBuilder();
|
||||
boolean nextUpperCase = false;
|
||||
|
||||
for (char c : columnName.toCharArray()) {
|
||||
if (c == '_') {
|
||||
nextUpperCase = true;
|
||||
} else {
|
||||
if (nextUpperCase) {
|
||||
result.append(Character.toUpperCase(c));
|
||||
nextUpperCase = false;
|
||||
} else {
|
||||
result.append(Character.toLowerCase(c));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* 将数据库类型映射为Java类型
|
||||
*/
|
||||
private static String mapDataTypeToJavaType(String dataType) {
|
||||
if (dataType == null) {
|
||||
return "String";
|
||||
}
|
||||
|
||||
dataType = dataType.toLowerCase();
|
||||
|
||||
switch (dataType) {
|
||||
case "tinyint":
|
||||
case "smallint":
|
||||
case "mediumint":
|
||||
case "int":
|
||||
return "Integer";
|
||||
case "bigint":
|
||||
return "Long";
|
||||
case "float":
|
||||
case "double":
|
||||
return "Double";
|
||||
case "decimal":
|
||||
case "numeric":
|
||||
return "BigDecimal";
|
||||
case "date":
|
||||
case "datetime":
|
||||
case "timestamp":
|
||||
return "Date";
|
||||
case "bit":
|
||||
return "Boolean";
|
||||
default:
|
||||
return "String";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查是否有特定类型的字段
|
||||
*/
|
||||
private static boolean hasFieldType(List<ColumnInfo> columns, String javaType) {
|
||||
if (columns == null || columns.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (ColumnInfo column : columns) {
|
||||
if (javaType.equals(column.getJavaType())) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
183
list.vue.ftl
183
list.vue.ftl
@ -1,183 +0,0 @@
|
||||
<template>
|
||||
<div class="app-container">
|
||||
<div class="filter-container">
|
||||
<el-input v-model="searchParams.keyword" placeholder="请输入关键词" style="width: 200px;" class="filter-item" @keyup.enter="handleQuery" />
|
||||
<el-button type="primary" icon="Search" @click="handleQuery" class="filter-item">搜索</el-button>
|
||||
<el-button icon="Refresh" @click="resetQuery" class="filter-item">重置</el-button>
|
||||
<el-button type="primary" icon="Plus" @click="handleAdd" class="filter-item">新增</el-button>
|
||||
</div>
|
||||
|
||||
<el-table
|
||||
v-loading="listLoading"
|
||||
:data="list"
|
||||
border
|
||||
fit
|
||||
highlight-current-row
|
||||
>
|
||||
<el-table-column type="selection" width="55" align="center" />
|
||||
<el-table-column label="ID" prop="id" width="80" align="center" />
|
||||
<!-- 根据实际字段动态生成表格列 -->
|
||||
<#if columns?? && columns.columns??>
|
||||
<#list columns.columns as column>
|
||||
<#assign columnName = column.columnName>
|
||||
<#assign propertyName = column.propertyName>
|
||||
<el-table-column label="${column.comment!columnName}" prop="${propertyName}" />
|
||||
</#list>
|
||||
</#if>
|
||||
|
||||
<el-table-column label="操作" width="200" align="center">
|
||||
<template #default="scope">
|
||||
<el-button size="small" type="text" @click="handleView(scope.row)">查看</el-button>
|
||||
<el-button size="small" type="text" @click="handleEdit(scope.row)">编辑</el-button>
|
||||
<el-button size="small" type="text" @click="handleDelete(scope.row)">删除</el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</el-table>
|
||||
|
||||
<el-pagination
|
||||
:current-page="pagination.currentPage"
|
||||
:page-size="pagination.pageSize"
|
||||
:total="pagination.total"
|
||||
:page-sizes="[10, 20, 50, 100]"
|
||||
layout="total, sizes, prev, pager, next, jumper"
|
||||
@size-change="handleSizeChange"
|
||||
@current-change="handleCurrentChange"
|
||||
/>
|
||||
|
||||
<!-- 新增/编辑弹窗 -->
|
||||
<el-dialog v-model="dialogVisible" :title="dialogTitle" width="500px">
|
||||
<${entityName}Form ref="formRef" :data="formData" />
|
||||
<template #footer>
|
||||
<el-button @click="dialogVisible = false">取消</el-button>
|
||||
<el-button type="primary" @click="handleSubmit">确定</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { ref, onMounted } from 'vue'
|
||||
import { get${entityName}List, delete${entityName} } from '@/api/${lowerEntityName}'
|
||||
import ${entityName}Form from './${entityName}Form.vue'
|
||||
import { ElMessage, ElConfirm } from 'element-plus'
|
||||
|
||||
// 列表数据
|
||||
const list = ref([])
|
||||
const listLoading = ref(false)
|
||||
|
||||
// 搜索参数
|
||||
const searchParams = ref({
|
||||
keyword: ''
|
||||
})
|
||||
|
||||
// 分页参数
|
||||
const pagination = ref({
|
||||
currentPage: 1,
|
||||
pageSize: 10,
|
||||
total: 0
|
||||
})
|
||||
|
||||
// 弹窗相关
|
||||
const dialogVisible = ref(false)
|
||||
const dialogTitle = ref('')
|
||||
const formData = ref({})
|
||||
const formRef = ref(null)
|
||||
|
||||
// 页面加载时查询数据
|
||||
onMounted(() => {
|
||||
handleQuery()
|
||||
})
|
||||
|
||||
// 查询数据
|
||||
const handleQuery = () => {
|
||||
listLoading.value = true
|
||||
get${entityName}List({
|
||||
pageNum: pagination.value.currentPage,
|
||||
pageSize: pagination.value.pageSize,
|
||||
...searchParams.value
|
||||
}).then(response => {
|
||||
list.value = response.data.records
|
||||
pagination.value.total = response.data.total
|
||||
listLoading.value = false
|
||||
}).catch(() => {
|
||||
listLoading.value = false
|
||||
})
|
||||
}
|
||||
|
||||
// 重置查询
|
||||
const resetQuery = () => {
|
||||
searchParams.value = {
|
||||
keyword: ''
|
||||
}
|
||||
pagination.value.currentPage = 1
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
// 分页大小变化
|
||||
const handleSizeChange = (val) => {
|
||||
pagination.value.pageSize = val
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
// 当前页变化
|
||||
const handleCurrentChange = (val) => {
|
||||
pagination.value.currentPage = val
|
||||
handleQuery()
|
||||
}
|
||||
|
||||
// 新增
|
||||
const handleAdd = () => {
|
||||
dialogTitle.value = '新增${entityName}'
|
||||
formData.value = {}
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 编辑
|
||||
const handleEdit = (row) => {
|
||||
dialogTitle.value = '编辑${entityName}'
|
||||
formData.value = { ...row }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 查看
|
||||
const handleView = (row) => {
|
||||
dialogTitle.value = '查看${entityName}'
|
||||
formData.value = { ...row }
|
||||
dialogVisible.value = true
|
||||
}
|
||||
|
||||
// 删除
|
||||
const handleDelete = (row) => {
|
||||
ElConfirm('确定要删除这条记录吗?', '提示', {
|
||||
confirmButtonText: '确定',
|
||||
cancelButtonText: '取消',
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
delete${entityName}(row.id).then(() => {
|
||||
ElMessage.success('删除成功')
|
||||
handleQuery()
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// 提交表单
|
||||
const handleSubmit = () => {
|
||||
formRef.value.validate(valid => {
|
||||
if (valid) {
|
||||
// 调用保存方法,实际项目中需要根据新增/编辑调用不同接口
|
||||
ElMessage.success('保存成功')
|
||||
dialogVisible.value = false
|
||||
handleQuery()
|
||||
}
|
||||
})
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.filter-container {
|
||||
padding: 10px 0;
|
||||
}
|
||||
.filter-item {
|
||||
margin-right: 10px;
|
||||
}
|
||||
</style>
|
||||
Loading…
x
Reference in New Issue
Block a user