feat: 代码生成器init
This commit is contained in:
parent
9e993b2b04
commit
650cbc12b4
|
@ -21,45 +21,45 @@ import java.util.List;
|
||||||
* @author Bunny
|
* @author Bunny
|
||||||
* @since ${date}
|
* @since ${date}
|
||||||
*/
|
*/
|
||||||
@Tag(name = "${classTitle}", description = "${classTitle}相关接口")
|
@Tag(name = "${classTitle}" , description = "${classTitle}相关接口" )
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("admin/${lowercaseName}")
|
@RequestMapping("admin/${lowercaseName}" )
|
||||||
public class ${originalName}Controller {
|
public class ${originalName}Controller {
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private ${originalName}Service ${lowercaseName}Service;
|
private ${originalName}Service ${lowercaseName}Service;
|
||||||
|
|
||||||
@Operation(summary = "分页查询${classTitle}", description = "分页查询${classTitle}")
|
@Operation(summary = "分页查询${classTitle}" , description = "分页查询${classTitle}" )
|
||||||
@GetMapping("get${originalName}List/{page}/{limit}")
|
@GetMapping("get${originalName}List/{page}/{limit}" )
|
||||||
public Mono<Result<PageResult<${originalName}Vo>>> get${originalName}List(
|
public Mono<Result<PageResult<${originalName}Vo>>> get${originalName}List(
|
||||||
@Parameter(name = "page", description = "当前页", required = true)
|
@Parameter(name = "page" , description = "当前页" , required = true)
|
||||||
@PathVariable("page") Integer page,
|
@PathVariable("page" ) Integer page,
|
||||||
@Parameter(name = "limit", description = "每页记录数", required = true)
|
@Parameter(name = "limit" , description = "每页记录数" , required = true)
|
||||||
@PathVariable("limit") Integer limit,
|
@PathVariable("limit" ) Integer limit,
|
||||||
${originalName}Dto dto) {
|
${originalName}Dto dto) {
|
||||||
Page<${originalName}> pageParams = new Page<>(page, limit);
|
Page<${originalName}> pageParams = new Page<>(page, limit);
|
||||||
PageResult<${originalName}Vo> pageResult = ${lowercaseName}Service.get${originalName}List(pageParams, dto);
|
PageResult<${originalName}Vo> pageResult = ${lowercaseName}Service.get${originalName}List(pageParams, dto);
|
||||||
return Mono.just(Result.success(pageResult));
|
return Mono.just(Result.success(pageResult));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "添加${classTitle}", description = "添加${classTitle}")
|
@Operation(summary = "添加${classTitle}" , description = "添加${classTitle}" )
|
||||||
@PostMapping("add${originalName}")
|
@PostMapping("add${originalName}" )
|
||||||
public Mono<Result<String>> add${originalName}(@Valid @RequestBody ${originalName}AddDto dto) {
|
public Mono<Result<String>> add${originalName}(@Valid @RequestBody ${originalName}AddDto dto) {
|
||||||
${lowercaseName}Service.add${originalName}(dto);
|
${lowercaseName}Service.add${originalName}(dto);
|
||||||
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
|
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "更新${classTitle}", description = "更新${classTitle}")
|
@Operation(summary = "更新${classTitle}" , description = "更新${classTitle}" )
|
||||||
@PutMapping("update${originalName}")
|
@PutMapping("update${originalName}" )
|
||||||
public Mono<Result<String>> update${originalName}(@Valid @RequestBody ${originalName}UpdateDto dto) {
|
public Mono<Result<String>> update${originalName}(@Valid @RequestBody ${originalName}UpdateDto dto) {
|
||||||
${lowercaseName}Service.update${originalName}(dto);
|
${lowercaseName}Service.update${originalName}(dto);
|
||||||
return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
|
return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Operation(summary = "删除${classTitle}", description = "删除${classTitle}")
|
@Operation(summary = "删除${classTitle}" , description = "删除${classTitle}" )
|
||||||
@DeleteMapping("delete${originalName}")
|
@DeleteMapping("delete${originalName}" )
|
||||||
public Mono<Result<String>> delete${originalName}(@RequestBody List<Long> ids) {
|
public Mono<Result<String>> delete${originalName}(@RequestBody List<Long> ids) {
|
||||||
${lowercaseName}Service.delete${originalName}(ids);
|
${lowercaseName}Service.delete${originalName}(ids);
|
||||||
return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS));
|
return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS));
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,75 @@
|
||||||
|
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
<parent>
|
||||||
|
<groupId>cn.bunny</groupId>
|
||||||
|
<artifactId>auth-server-java</artifactId>
|
||||||
|
<version>0.0.1-SNAPSHOT</version>
|
||||||
|
<relativePath>../../pom.xml</relativePath>
|
||||||
|
</parent>
|
||||||
|
|
||||||
|
<artifactId>generator-code</artifactId>
|
||||||
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
|
<name>generator-code</name>
|
||||||
|
<url>https://maven.apache.org</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-thymeleaf</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>junit</groupId>
|
||||||
|
<artifactId>junit</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.xerial</groupId>
|
||||||
|
<artifactId>sqlite-jdbc</artifactId>
|
||||||
|
<version>3.49.1.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.mysql</groupId>
|
||||||
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.zaxxer</groupId>
|
||||||
|
<artifactId>HikariCP</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.baomidou</groupId>
|
||||||
|
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>cn.hutool</groupId>
|
||||||
|
<artifactId>hutool-all</artifactId>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.velocity</groupId>
|
||||||
|
<artifactId>velocity-engine-core</artifactId>
|
||||||
|
<version>2.3</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
</dependencies>
|
||||||
|
</project>
|
|
@ -0,0 +1,13 @@
|
||||||
|
package cn.bunny;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.transaction.annotation.EnableTransactionManagement;
|
||||||
|
|
||||||
|
@EnableTransactionManagement
|
||||||
|
@SpringBootApplication
|
||||||
|
public class GeneratorCodeMainApplication {
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(GeneratorCodeMainApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package cn.bunny.config;
|
||||||
|
|
||||||
|
import jakarta.annotation.PostConstruct;
|
||||||
|
import lombok.Getter;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import javax.sql.DataSource;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DatabaseMetadataHolder {
|
||||||
|
@Getter
|
||||||
|
private DatabaseMetaData metaData;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSource dataSource;
|
||||||
|
|
||||||
|
@PostConstruct
|
||||||
|
public void init() throws SQLException {
|
||||||
|
try (Connection connection = dataSource.getConnection()) {
|
||||||
|
this.metaData = connection.getMetaData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
package cn.bunny.controller;
|
||||||
|
|
||||||
|
import cn.bunny.service.IndexService;
|
||||||
|
import org.springframework.stereotype.Controller;
|
||||||
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
|
||||||
|
@Controller
|
||||||
|
@RequestMapping("/")
|
||||||
|
public class IndexController {
|
||||||
|
|
||||||
|
private final IndexService indexService;
|
||||||
|
|
||||||
|
public IndexController(IndexService indexService) {
|
||||||
|
this.indexService = indexService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@GetMapping("/")
|
||||||
|
public String index() {
|
||||||
|
return "index";
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
package cn.bunny.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class ColumnMetaData {
|
||||||
|
|
||||||
|
/* 列名称 */
|
||||||
|
private String columnName;
|
||||||
|
|
||||||
|
/* 字段名称 */
|
||||||
|
private String fieldName;
|
||||||
|
|
||||||
|
/* 数据库字段类型 */
|
||||||
|
private String jdbcType;
|
||||||
|
|
||||||
|
/* Java类型 */
|
||||||
|
private String javaType;
|
||||||
|
|
||||||
|
/* 是否为主键 */
|
||||||
|
private Boolean isPrimaryKey;
|
||||||
|
|
||||||
|
/* 字段注释 */
|
||||||
|
private String comment;
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,54 @@
|
||||||
|
package cn.bunny.entity;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Builder;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
@Builder
|
||||||
|
@AllArgsConstructor
|
||||||
|
@NoArgsConstructor
|
||||||
|
public class TableMetaData {
|
||||||
|
|
||||||
|
/* 表目录 */
|
||||||
|
private String tableCat;
|
||||||
|
|
||||||
|
/* 表模式(可能为null) */
|
||||||
|
private String tableSchem;
|
||||||
|
|
||||||
|
/* 表类型(通常是"TABLE") */
|
||||||
|
private String tableType;
|
||||||
|
|
||||||
|
/* 表的注释/描述 */
|
||||||
|
private String remarks;
|
||||||
|
|
||||||
|
/* 类型的目录(可能为null) */
|
||||||
|
private String typeCat;
|
||||||
|
|
||||||
|
/* 类型的模式(可能为null) */
|
||||||
|
private String typeSchem;
|
||||||
|
|
||||||
|
/* 类型名称(可能为null) */
|
||||||
|
private String typeName;
|
||||||
|
|
||||||
|
/* 自引用列名(可能为null) */
|
||||||
|
private String selfReferencingColName;
|
||||||
|
|
||||||
|
/* 引用生成(可能为null) */
|
||||||
|
private String refGeneration;
|
||||||
|
|
||||||
|
/* 表名 */
|
||||||
|
private String tableName;
|
||||||
|
|
||||||
|
/* 类名 */
|
||||||
|
private String className;
|
||||||
|
|
||||||
|
/* 注释内哦让那个 */
|
||||||
|
private String comment;
|
||||||
|
|
||||||
|
/* 列名称 */
|
||||||
|
private List<ColumnMetaData> columns;
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
package cn.bunny.service;
|
||||||
|
|
||||||
|
public interface IndexService {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
package cn.bunny.service.impl;
|
||||||
|
|
||||||
|
import cn.bunny.service.IndexService;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class IndexServiceImpl implements IndexService {
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
package cn.bunny.utils;
|
||||||
|
|
||||||
|
public class ConvertUtil {
|
||||||
|
/**
|
||||||
|
* 将数据库类型转换为Java类型
|
||||||
|
*/
|
||||||
|
public static String convertToJavaType(String columnType) {
|
||||||
|
if (columnType == null) return "Object";
|
||||||
|
|
||||||
|
columnType = columnType.toLowerCase();
|
||||||
|
return switch (columnType) {
|
||||||
|
case "varchar" , "char" , "text" , "longtext" , "mediumtext" , "tinytext" -> "String";
|
||||||
|
case "int" , "integer" , "tinyint" , "smallint" -> "Integer";
|
||||||
|
case "bigint" -> "Long";
|
||||||
|
case "decimal" , "numeric" -> "BigDecimal";
|
||||||
|
case "float" -> "Float";
|
||||||
|
case "double" -> "Double";
|
||||||
|
case "boolean" , "bit" , "tinyint unsigned" -> "Boolean";
|
||||||
|
case "date" , "year" -> "Date";
|
||||||
|
case "time" -> "Time";
|
||||||
|
case "datetime" , "timestamp" -> "LocalDateTime";
|
||||||
|
case "blob" , "longblob" , "mediumblob" , "tinyblob" -> "byte[]";
|
||||||
|
default -> "Object";
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下划线命名转驼峰命名
|
||||||
|
*/
|
||||||
|
public static String convertToCamelCase(String name) {
|
||||||
|
return convertToCamelCase(name, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 下划线命名转驼峰命名
|
||||||
|
*
|
||||||
|
* @param name 原始名称
|
||||||
|
* @param firstLetterCapital 首字母是否大写
|
||||||
|
*/
|
||||||
|
public static String convertToCamelCase(String name, boolean firstLetterCapital) {
|
||||||
|
if (name == null || name.isEmpty()) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuilder result = new StringBuilder();
|
||||||
|
String[] parts = name.split("_" );
|
||||||
|
|
||||||
|
for (int i = 0; i < parts.length; i++) {
|
||||||
|
String part = parts[i];
|
||||||
|
if (part.isEmpty()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == 0 && !firstLetterCapital) {
|
||||||
|
result.append(part.toLowerCase());
|
||||||
|
} else {
|
||||||
|
result.append(Character.toUpperCase(part.charAt(0)))
|
||||||
|
.append(part.substring(1).toLowerCase());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 辅助方法:将列名转换为字段名(如user_name -> userName)
|
||||||
|
*
|
||||||
|
* @param columnName 列名称
|
||||||
|
* @return 列名称
|
||||||
|
*/
|
||||||
|
public static String convertToFieldName(String columnName) {
|
||||||
|
String[] parts = columnName.split("_" );
|
||||||
|
StringBuilder fieldName = new StringBuilder(parts[0].toLowerCase());
|
||||||
|
for (int i = 1; i < parts.length; i++) {
|
||||||
|
fieldName.append(parts[i].substring(0, 1).toUpperCase())
|
||||||
|
.append(parts[i].substring(1).toLowerCase());
|
||||||
|
}
|
||||||
|
return fieldName.toString();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,103 @@
|
||||||
|
package cn.bunny.utils;
|
||||||
|
|
||||||
|
import cn.bunny.config.DatabaseMetadataHolder;
|
||||||
|
import cn.bunny.entity.ColumnMetaData;
|
||||||
|
import cn.bunny.entity.TableMetaData;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
public class DbInfoUtil {
|
||||||
|
@Autowired
|
||||||
|
private DatabaseMetadataHolder metadataHolder;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取表注释信息
|
||||||
|
*
|
||||||
|
* @param tableName 数据库表名
|
||||||
|
* @return 表信息
|
||||||
|
* @throws SQLException SQLException
|
||||||
|
*/
|
||||||
|
public TableMetaData tableInfo(String tableName) throws SQLException {
|
||||||
|
TableMetaData tableMetaData = null;
|
||||||
|
DatabaseMetaData metaData = metadataHolder.getMetaData();
|
||||||
|
ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
|
||||||
|
|
||||||
|
// 获取表的注释信息
|
||||||
|
if (tables.next()) {
|
||||||
|
String remarks = tables.getString("REMARKS" );
|
||||||
|
String tableCat = tables.getString("TABLE_CAT" );
|
||||||
|
String tableSchem = tables.getString("TABLE_SCHEM" );
|
||||||
|
String tableType = tables.getString("TABLE_TYPE" );
|
||||||
|
String typeCat = tables.getString("TYPE_CAT" );
|
||||||
|
String typeSchem = tables.getString("TYPE_SCHEM" );
|
||||||
|
String typeName = tables.getString("TYPE_NAME" );
|
||||||
|
String selfReferencingColName = tables.getString("SELF_REFERENCING_COL_NAME" );
|
||||||
|
String refGeneration = tables.getString("REF_GENERATION" );
|
||||||
|
|
||||||
|
tableMetaData = TableMetaData.builder()
|
||||||
|
.tableName(tableName)
|
||||||
|
.remarks(remarks)
|
||||||
|
.tableCat(tableCat)
|
||||||
|
.tableSchem(tableSchem)
|
||||||
|
.tableType(tableType)
|
||||||
|
.typeCat(typeCat)
|
||||||
|
.typeSchem(typeSchem)
|
||||||
|
.typeName(typeName)
|
||||||
|
.selfReferencingColName(selfReferencingColName)
|
||||||
|
.refGeneration(refGeneration)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return tableMetaData;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库列信息
|
||||||
|
*
|
||||||
|
* @param tableName 表名
|
||||||
|
* @return 列表信息
|
||||||
|
* @throws SQLException SQLException
|
||||||
|
*/
|
||||||
|
public List<ColumnMetaData> columnInfo(String tableName) throws SQLException {
|
||||||
|
DatabaseMetaData metaData = metadataHolder.getMetaData();
|
||||||
|
List<ColumnMetaData> columns = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ResultSet columnsRs = metaData.getColumns(null, null, tableName, null)) {
|
||||||
|
while (columnsRs.next()) {
|
||||||
|
ColumnMetaData column = new ColumnMetaData();
|
||||||
|
column.setColumnName(columnsRs.getString("COLUMN_NAME" ));
|
||||||
|
column.setFieldName(ConvertUtil.convertToFieldName(column.getColumnName()));
|
||||||
|
column.setJdbcType(columnsRs.getString("TYPE_NAME" ));
|
||||||
|
column.setJavaType(ConvertUtil.convertToJavaType(column.getJdbcType()));
|
||||||
|
column.setComment(columnsRs.getString("REMARKS" ));
|
||||||
|
|
||||||
|
columns.add(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return columns;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 数据库所有的信息
|
||||||
|
*
|
||||||
|
* @param tableName 表名
|
||||||
|
* @return 表内容
|
||||||
|
* @throws SQLException SQLException
|
||||||
|
*/
|
||||||
|
public TableMetaData dbInfo(String tableName) throws SQLException {
|
||||||
|
List<ColumnMetaData> columnMetaData = columnInfo(tableName);
|
||||||
|
TableMetaData tableMetaData = tableInfo(tableName);
|
||||||
|
|
||||||
|
tableMetaData.setColumns(columnMetaData);
|
||||||
|
|
||||||
|
return tableMetaData;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
bunny:
|
||||||
|
master:
|
||||||
|
host: 192.168.3.137
|
||||||
|
port: 3306
|
||||||
|
database: auth_admin
|
||||||
|
username: root
|
||||||
|
password: "123456"
|
||||||
|
connect:
|
||||||
|
url: jdbc:sqlite::resource:database.sqlite
|
||||||
|
username: root
|
||||||
|
password: "123456"
|
|
@ -0,0 +1,31 @@
|
||||||
|
server:
|
||||||
|
port: 9999
|
||||||
|
|
||||||
|
spring:
|
||||||
|
profiles:
|
||||||
|
active: dev
|
||||||
|
application:
|
||||||
|
name: generator-code
|
||||||
|
thymeleaf:
|
||||||
|
check-template-location: false
|
||||||
|
|
||||||
|
datasource:
|
||||||
|
dynamic:
|
||||||
|
primary: master #设置默认的数据源或者数据源组,默认值即为master
|
||||||
|
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
|
||||||
|
grace-destroy: false #是否优雅关闭数据源,默认为false,设置为true时,关闭数据源时如果数据源中还存在活跃连接,至多等待10s后强制关闭
|
||||||
|
datasource:
|
||||||
|
master:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
driver-class-name: com.mysql.cj.jdbc.Driver
|
||||||
|
url: jdbc:mysql://${bunny.master.host}:${bunny.master.port}/${bunny.master.database}?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true
|
||||||
|
username: ${bunny.master.username}
|
||||||
|
password: ${bunny.master.password}
|
||||||
|
connect:
|
||||||
|
type: com.zaxxer.hikari.HikariDataSource
|
||||||
|
driver-class-name: org.sqlite.JDBC
|
||||||
|
url: ${bunny.connect.url}
|
||||||
|
username: ${bunny.connect.username}
|
||||||
|
password: ${bunny.connect.password}
|
||||||
|
aop:
|
||||||
|
enabled: true
|
|
@ -0,0 +1,10 @@
|
||||||
|
_ _
|
||||||
|
| |__ _ _ _ __ _ __ _ _ (_) __ ___ ____ _
|
||||||
|
| '_ \| | | | '_ \| '_ \| | | | | |/ _` \ \ / / _` |
|
||||||
|
| |_) | |_| | | | | | | | |_| | | | (_| |\ V | (_| |
|
||||||
|
|_.__/ \__,_|_| |_|_| |_|\__, | _/ |\__,_| \_/ \__,_|
|
||||||
|
|___/ |__/
|
||||||
|
|
||||||
|
Service Name${spring.application.name}
|
||||||
|
SpringBoot Version: ${spring-boot.version}${spring-boot.formatted-version}
|
||||||
|
SpringActive:${spring.profiles.active}
|
|
@ -0,0 +1,20 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/@tailwindcss/browser@4"></script>
|
||||||
|
<title>主页</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>666</h1>
|
||||||
|
<button class="bg-red-500">555</button>
|
||||||
|
|
||||||
|
<form action="">
|
||||||
|
<label>
|
||||||
|
111:
|
||||||
|
<input class="border-2 border-solid" type="text">
|
||||||
|
</label>
|
||||||
|
|
||||||
|
</form>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,65 @@
|
||||||
|
package cn.bunny.services.controller;
|
||||||
|
|
||||||
|
import cn.bunny.dao.pojo.result.Result;
|
||||||
|
import cn.bunny.dao.pojo.result.ResultCodeEnum;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import reactor.core.publisher.Mono;
|
||||||
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* ${classTitle}表 前端控制器
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Bunny
|
||||||
|
* @since ${date}
|
||||||
|
*/
|
||||||
|
@Tag(name = "${classTitle}" , description = "${classTitle}相关接口" )
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("admin/${lowercaseName}" )
|
||||||
|
public class ${originalName}Controller {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private ${originalName}Service ${lowercaseName}Service;
|
||||||
|
|
||||||
|
@Operation(summary = "分页查询${classTitle}" , description = "分页查询${classTitle}" )
|
||||||
|
@GetMapping("get${originalName}List/{page}/{limit}" )
|
||||||
|
public Mono<Result<PageResult<${originalName}Vo>>> get${originalName}List(
|
||||||
|
@Parameter(name = "page" , description = "当前页" , required = true)
|
||||||
|
@PathVariable("page" ) Integer page,
|
||||||
|
@Parameter(name = "limit" , description = "每页记录数" , required = true)
|
||||||
|
@PathVariable("limit" ) Integer limit,
|
||||||
|
${originalName}Dto dto) {
|
||||||
|
Page<${originalName}> pageParams = new Page<>(page, limit);
|
||||||
|
PageResult<${originalName}Vo> pageResult = ${lowercaseName}Service.get${originalName}List(pageParams, dto);
|
||||||
|
return Mono.just(Result.success(pageResult));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "添加${classTitle}" , description = "添加${classTitle}" )
|
||||||
|
@PostMapping("add${originalName}" )
|
||||||
|
public Mono<Result<String>> add${originalName}(@Valid @RequestBody ${originalName}AddDto dto) {
|
||||||
|
${lowercaseName}Service.add${originalName}(dto);
|
||||||
|
return Mono.just(Result.success(ResultCodeEnum.ADD_SUCCESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "更新${classTitle}" , description = "更新${classTitle}" )
|
||||||
|
@PutMapping("update${originalName}" )
|
||||||
|
public Mono<Result<String>> update${originalName}(@Valid @RequestBody ${originalName}UpdateDto dto) {
|
||||||
|
${lowercaseName}Service.update${originalName}(dto);
|
||||||
|
return Mono.just(Result.success(ResultCodeEnum.UPDATE_SUCCESS));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "删除${classTitle}" , description = "删除${classTitle}" )
|
||||||
|
@DeleteMapping("delete${originalName}" )
|
||||||
|
public Mono<Result<String>> delete${originalName}(@RequestBody List<Long> ids) {
|
||||||
|
${lowercaseName}Service.delete${originalName}(ids);
|
||||||
|
return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS));
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,35 @@
|
||||||
|
package cn.bunny.services.mapper;
|
||||||
|
|
||||||
|
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
|
||||||
|
import org.apache.ibatis.annotations.Mapper;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import org.apache.ibatis.annotations.Param;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* ${classTitle} Mapper 接口
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Bunny
|
||||||
|
* @since ${date}
|
||||||
|
*/
|
||||||
|
@Mapper
|
||||||
|
public interface ${originalName}Mapper extends BaseMapper<${originalName}> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 分页查询${classTitle}内容
|
||||||
|
*
|
||||||
|
* @param pageParams ${classTitle}分页参数
|
||||||
|
* @param dto ${classTitle}查询表单
|
||||||
|
* @return ${classTitle}分页结果
|
||||||
|
*/
|
||||||
|
IPage<${originalName}Vo> selectListByPage(@Param("page") Page<${originalName}> pageParams, @Param("dto") ${originalName}Dto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 物理删除${classTitle}
|
||||||
|
*
|
||||||
|
* @param ids 删除 id 列表
|
||||||
|
*/
|
||||||
|
void deleteBatchIdsWithPhysics(List<Long> ids);
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
|
||||||
|
<mapper namespace="cn.bunny.services.mapper.${originalName}Mapper">
|
||||||
|
|
||||||
|
<!-- 通用查询映射结果 -->
|
||||||
|
<resultMap id="BaseResultMap" type="$type">
|
||||||
|
#foreach($field in $baseResultMaps)
|
||||||
|
<id column="$field.column" property="$field.property"/>
|
||||||
|
#end
|
||||||
|
</resultMap>
|
||||||
|
|
||||||
|
<!-- 通用查询结果列 -->
|
||||||
|
<sql id="Base_Column_List">
|
||||||
|
$baseColumnList
|
||||||
|
</sql>
|
||||||
|
|
||||||
|
<!-- 分页查询${classTitle}内容 -->
|
||||||
|
<select id="selectListByPage" resultType="${voClassType}">
|
||||||
|
select
|
||||||
|
base.*,
|
||||||
|
create_user.username as create_username,
|
||||||
|
update_user.username as update_username
|
||||||
|
from $tableName base
|
||||||
|
left join sys_user create_user on create_user.id = base.create_user
|
||||||
|
left join sys_user update_user on update_user.id = base.update_user
|
||||||
|
<where>
|
||||||
|
base.is_deleted = 0
|
||||||
|
#foreach($field in $pageQueryMap)
|
||||||
|
<if test="dto.${field.property} != null and dto.${field.property} != ''">
|
||||||
|
and base.$field.column like CONCAT('%',#{dto.${field.property}},'%')
|
||||||
|
</if>
|
||||||
|
#end
|
||||||
|
</where>
|
||||||
|
</select>
|
||||||
|
|
||||||
|
<!-- 物理删除${classTitle} -->
|
||||||
|
<delete id="deleteBatchIdsWithPhysics">
|
||||||
|
delete
|
||||||
|
from $tableName
|
||||||
|
where id in
|
||||||
|
<foreach collection="ids" item="id" open="(" close=")" separator=",">
|
||||||
|
#{id}
|
||||||
|
</foreach>
|
||||||
|
</delete>
|
||||||
|
|
||||||
|
</mapper>
|
|
@ -0,0 +1,49 @@
|
||||||
|
package cn.bunny.services.service;
|
||||||
|
|
||||||
|
import cn.bunny.dao.entity.system.MenuIcon;
|
||||||
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.IService;
|
||||||
|
import jakarta.validation.Valid;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* ${classTitle} 服务类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Bunny
|
||||||
|
* @since ${date}
|
||||||
|
*/
|
||||||
|
public interface ${originalName}Service extends IService<${originalName}> {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 获取${classTitle}列表
|
||||||
|
*
|
||||||
|
* @return ${classTitle}返回列表
|
||||||
|
*/
|
||||||
|
PageResult<${originalName}Vo> get${originalName}List(Page<${originalName}> pageParams, ${originalName}Dto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 添加${classTitle}
|
||||||
|
*
|
||||||
|
* @param dto 添加表单
|
||||||
|
*/
|
||||||
|
void add${originalName}(@Valid ${originalName}AddDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 更新${classTitle}
|
||||||
|
*
|
||||||
|
* @param dto 更新表单
|
||||||
|
*/
|
||||||
|
void update${originalName}(@Valid ${originalName}UpdateDto dto);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * 删除|批量删除${classTitle}类型
|
||||||
|
*
|
||||||
|
* @param ids 删除id列表
|
||||||
|
*/
|
||||||
|
void delete${originalName}(List<Long> ids);
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
package cn.bunny.services.service.impl;
|
||||||
|
|
||||||
|
import cn.bunny.dao.pojo.result.PageResult;
|
||||||
|
import cn.bunny.services.mapper.${originalName}Mapper;
|
||||||
|
import cn.bunny.services.service.${originalName}Service;
|
||||||
|
import com.baomidou.mybatisplus.core.metadata.IPage;
|
||||||
|
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||||
|
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* ${classTitle} 服务实现类
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Bunny
|
||||||
|
* @since ${date}
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class ${originalName}ServiceImpl extends ServiceImpl<${originalName}Mapper, ${originalName}> implements ${originalName}Service {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* * ${classTitle} 服务实现类
|
||||||
|
*
|
||||||
|
* @param pageParams ${classTitle}分页查询page对象
|
||||||
|
* @param dto ${classTitle}分页查询对象
|
||||||
|
* @return 查询分页${classTitle}返回对象
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public PageResult<${originalName}Vo> get${originalName}List(Page<${originalName}> pageParams, ${originalName}Dto dto) {
|
||||||
|
IPage<${originalName}Vo> page = baseMapper.selectListByPage(pageParams, dto);
|
||||||
|
|
||||||
|
return PageResult.<${originalName}Vo>builder()
|
||||||
|
.list(page.getRecords())
|
||||||
|
.pageNo(page.getCurrent())
|
||||||
|
.pageSize(page.getSize())
|
||||||
|
.total(page.getTotal())
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* 添加${classTitle}
|
||||||
|
*
|
||||||
|
* @param dto ${classTitle}添加
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void add${originalName}(@Valid ${originalName}AddDto dto) {
|
||||||
|
// 保存数据
|
||||||
|
${originalName} ${lowercaseName} = new ${originalName}();
|
||||||
|
BeanUtils.copyProperties(dto, ${lowercaseName});
|
||||||
|
save(${lowercaseName});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新${classTitle}
|
||||||
|
*
|
||||||
|
* @param dto ${classTitle}更新
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void update${originalName}(@Valid ${originalName}UpdateDto dto) {
|
||||||
|
// 更新内容
|
||||||
|
${originalName} ${lowercaseName} = new ${originalName}();
|
||||||
|
BeanUtils.copyProperties(dto, ${lowercaseName});
|
||||||
|
updateById(${lowercaseName});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除|批量删除${classTitle}
|
||||||
|
*
|
||||||
|
* @param ids 删除id列表
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void delete${originalName}(List<Long> ids) {
|
||||||
|
baseMapper.deleteBatchIdsWithPhysics(ids);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
import { http } from '@/api/service/request';
|
||||||
|
import type { BaseResult, ResultTable } from '@/api/service/types';
|
||||||
|
|
||||||
|
/** ${classDescription}---获取${classDescription}列表 */
|
||||||
|
export const fetchGet${originalName}List = (data: any) => {
|
||||||
|
return http.request<BaseResult<ResultTable>>('get', `${lowercaseName}/get${originalName}List/${data.currentPage}/${data.pageSize}`, { params: data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ${classDescription}---添加${classDescription} */
|
||||||
|
export const fetchAdd${originalName} = (data: any) => {
|
||||||
|
return http.request<BaseResult<object>>('post', '${lowercaseName}/add${originalName}', { data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ${classDescription}---更新${classDescription} */
|
||||||
|
export const fetchUpdate${originalName} = (data: any) => {
|
||||||
|
return http.request<BaseResult<object>>('put', '${lowercaseName}/update${originalName}', { data });
|
||||||
|
};
|
||||||
|
|
||||||
|
/** ${classDescription}---删除${classDescription} */
|
||||||
|
export const fetchDelete${originalName} = (data: any) => {
|
||||||
|
return http.request<BaseResult<object>>('delete', '${lowercaseName}/delete${originalName}', { data });
|
||||||
|
};
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { reactive, ref } from 'vue';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import type { FormRules } from 'element-plus';
|
||||||
|
|
||||||
|
// 表格列
|
||||||
|
export const columns: TableColumnList = [
|
||||||
|
{ type: 'selection', align: 'left' },
|
||||||
|
{ type: 'index', index: (index: number) => index + 1, label: '序号', width: 60 },
|
||||||
|
#foreach($field in $baseFieldList)
|
||||||
|
// $field.annotation
|
||||||
|
{ label: $t('$field.name'), prop: '$field.name' },
|
||||||
|
#end
|
||||||
|
{ label: $t('table.updateTime'), prop: 'updateTime', sortable: true, width: 160 },
|
||||||
|
{ label: $t('table.createTime'), prop: 'createTime', sortable: true, width: 160 },
|
||||||
|
{ label: $t('table.createUser'), prop: 'createUser', slot: 'createUser', width: 130 },
|
||||||
|
{ label: $t('table.updateUser'), prop: 'updateUser', slot: 'updateUser', width: 130 },
|
||||||
|
{ label: $t('table.operation'), fixed: 'right', width: 210, slot: 'operation' },
|
||||||
|
];
|
||||||
|
|
||||||
|
// 添加规则
|
||||||
|
export const rules = reactive
|
||||||
|
<FormRules>({
|
||||||
|
#foreach($field in $baseFieldList)
|
||||||
|
// $field.annotation
|
||||||
|
$field.name: [{ required: true, message: `$leftBrace$t('input')}$leftBrace$t('${field.name}')}`, trigger: 'blur' }],
|
||||||
|
#end
|
||||||
|
});
|
|
@ -0,0 +1,36 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { ref } from 'vue';
|
||||||
|
import { FormInstance } from 'element-plus';
|
||||||
|
import { rules } from '${columnsPath}';
|
||||||
|
import { FormProps } from '${typesPath}';
|
||||||
|
import { frameSureOptions } from '@/enums';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
|
||||||
|
const props = withDefaults(defineProps<FormProps>(), {
|
||||||
|
formInline: () => ({
|
||||||
|
#foreach($item in $baseFieldList)
|
||||||
|
#if(${item.name})
|
||||||
|
// $!{item.annotation}
|
||||||
|
${item.name}: undefined,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
const formRef = ref<FormInstance>();
|
||||||
|
const form = ref(props.formInline);
|
||||||
|
|
||||||
|
defineExpose({ formRef });
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<el-form ref="formRef" :model="form" :rules="rules" label-width="auto">
|
||||||
|
#foreach($item in $baseFieldList)
|
||||||
|
|
||||||
|
<!-- $item.annotation -->
|
||||||
|
<el-form-item :label="$t('${item.name}')" prop="$item.name">
|
||||||
|
<el-input v-model="form.$item.name" autocomplete="off" type="text" :placeholder="$t('input') + $t('${item.name}')" />
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
</el-form>
|
||||||
|
</template>
|
|
@ -0,0 +1,130 @@
|
||||||
|
import { deviceDetection } from '@pureadmin/utils';
|
||||||
|
import { addDialog } from '@/components/BaseDialog/index';
|
||||||
|
import ${originalName}Dialog from '${dialogPath}';
|
||||||
|
import { use${originalName}Store } from '${storePath}';
|
||||||
|
import { h, ref } from 'vue';
|
||||||
|
import { messageBox } from '@/utils/message';
|
||||||
|
import type { FormItemProps } from '${typesPath}';
|
||||||
|
import { $t } from '@/plugins/i18n';
|
||||||
|
import { message, messageBox } from "@/utils/message";
|
||||||
|
import DeleteBatchDialog from "@/components/Table/DeleteBatchDialog.vue";
|
||||||
|
|
||||||
|
export const formRef = ref();
|
||||||
|
// 删除ids
|
||||||
|
export const deleteIds = ref([]);
|
||||||
|
const ${lowercaseName}Store = use${originalName}Store();
|
||||||
|
|
||||||
|
/** 搜索初始化${classTitle} */
|
||||||
|
export async function onSearch() {
|
||||||
|
${lowercaseName}Store.loading = true;
|
||||||
|
await ${lowercaseName}Store.get${originalName}List();
|
||||||
|
${lowercaseName}Store.loading = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加${classTitle} */
|
||||||
|
export function onAdd() {
|
||||||
|
addDialog({
|
||||||
|
title: `$leftBrace $t("addNew")}$leftBrace$t("${lowercaseName}")}`,
|
||||||
|
width: '30%',
|
||||||
|
props: {
|
||||||
|
formInline: {
|
||||||
|
#foreach($item in $addFormList)
|
||||||
|
$!{item}: undefined,
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
},
|
||||||
|
draggable: true,
|
||||||
|
fullscreenIcon: true,
|
||||||
|
closeOnClickModal: false,
|
||||||
|
contentRenderer: () => h(${originalName}Dialog, { ref: formRef }),
|
||||||
|
beforeSure: (done, { options }) => {
|
||||||
|
const form = options.props.formInline as FormItemProps;
|
||||||
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const result = await ${lowercaseName}Store.add${originalName}(form);
|
||||||
|
if (!result) return;
|
||||||
|
done();
|
||||||
|
await onSearch();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 更新${classTitle} */
|
||||||
|
export function onUpdate(row: any) {
|
||||||
|
addDialog({
|
||||||
|
title: `$leftBrace$t("modify")}$leftBrace$t("${lowercaseName}")}`,
|
||||||
|
width: '30%',
|
||||||
|
props: {
|
||||||
|
formInline: {
|
||||||
|
#foreach($item in $addFormList)
|
||||||
|
$!{item}: row.$!{item},
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
},
|
||||||
|
draggable: true,
|
||||||
|
fullscreenIcon: true,
|
||||||
|
closeOnClickModal: false,
|
||||||
|
contentRenderer: () => h(${originalName}Dialog, { ref: formRef }),
|
||||||
|
beforeSure: (done, { options }) => {
|
||||||
|
const form = options.props.formInline as FormItemProps;
|
||||||
|
formRef.value.formRef.validate(async (valid: any) => {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const result = await ${lowercaseName}Store.update${originalName}({ ...form, id: row.id });
|
||||||
|
if (!result) return;
|
||||||
|
done();
|
||||||
|
await onSearch();
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除${classTitle} */
|
||||||
|
export const onDelete = async (row: any) => {
|
||||||
|
const id = row.id;
|
||||||
|
|
||||||
|
// 是否确认删除
|
||||||
|
const result = await messageBox({
|
||||||
|
title: $t('confirmDelete'),
|
||||||
|
showMessage: false,
|
||||||
|
confirmMessage: undefined,
|
||||||
|
cancelMessage: $t("cancel_delete"),
|
||||||
|
});
|
||||||
|
if (!result) return;
|
||||||
|
|
||||||
|
// 删除数据
|
||||||
|
await ${lowercaseName}Store.delete${originalName}([id]);
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 批量删除 */
|
||||||
|
export const onDeleteBatch = async () => {
|
||||||
|
const ids = deleteIds.value;
|
||||||
|
const formDeletedBatchRef = ref();
|
||||||
|
|
||||||
|
addDialog({
|
||||||
|
title: $t('deleteBatchTip'),
|
||||||
|
width: '30%',
|
||||||
|
props: { formInline: { confirmText: '' } },
|
||||||
|
draggable: true,
|
||||||
|
fullscreenIcon: true,
|
||||||
|
closeOnClickModal: false,
|
||||||
|
contentRenderer: () => h(DeleteBatchDialog, { ref: formDeletedBatchRef }),
|
||||||
|
beforeSure: (done, { options }) => {
|
||||||
|
formDeletedBatchRef.value.formDeletedBatchRef.validate(async (valid: any) => {
|
||||||
|
if (!valid) return;
|
||||||
|
|
||||||
|
const text = options.props.formInline.confirmText.toLowerCase();
|
||||||
|
if (text === 'yes' || text === 'y') {
|
||||||
|
// 删除数据
|
||||||
|
await ${lowercaseName}Store.delete${originalName}(ids);
|
||||||
|
await onSearch();
|
||||||
|
|
||||||
|
done();
|
||||||
|
} else message($t('deleteBatchTip'), { type: 'warning' });
|
||||||
|
});
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
|
@ -0,0 +1,121 @@
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import {onMounted, ref} from 'vue';
|
||||||
|
import {deleteIds, onSearch} from '';
|
||||||
|
import {FormInstance} from "element-plus";
|
||||||
|
|
||||||
|
const tableRef = ref();
|
||||||
|
const formRef = ref();
|
||||||
|
const ${lowercaseName}Store = use${originalName}Store();
|
||||||
|
|
||||||
|
/** 当前页改变时 */
|
||||||
|
const onCurrentPageChange = async (value: number) => {
|
||||||
|
${lowercaseName}Store.pagination.currentPage = value;
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 当分页发生变化 */
|
||||||
|
const onPageSizeChange = async (value: number) => {
|
||||||
|
${lowercaseName}Store.pagination.pageSize = value;
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 选择多行 */
|
||||||
|
const onSelectionChange = (rows: Array<any>) => {
|
||||||
|
deleteIds.value = rows.map((row: any) => row.id);
|
||||||
|
};
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = async (formEl: FormInstance | undefined) => {
|
||||||
|
if (!formEl) return;
|
||||||
|
formEl.resetFields();
|
||||||
|
await onSearch();
|
||||||
|
};
|
||||||
|
|
||||||
|
onMounted(() => {
|
||||||
|
onSearch();
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="main">
|
||||||
|
<el-form ref="formRef" :inline="true" :model="${lowercaseName}Store.form" class="search-form bg-bg_color w-[99/100] pl-8 pt-[12px] overflow-auto">
|
||||||
|
#foreach($item in $formList)
|
||||||
|
|
||||||
|
<!-- $item.annotation -->
|
||||||
|
<el-form-item :label="$t('${item.name}')" prop="${item.name}">
|
||||||
|
<el-input v-model="${lowercaseName}Store.form.${item.name}" :placeholder="`$leftBrace$t('input')}$leftBrace$t('${item.name}')}`"
|
||||||
|
class="!w-[180px]" clearable/>
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
<el-form-item>
|
||||||
|
<el-button :icon="useRenderIcon('ri:search-line')" :loading="${lowercaseName}Store.loading" type="primary" @click="onSearch"> {{ $t('search')
|
||||||
|
}}
|
||||||
|
</el-button>
|
||||||
|
<el-button :icon="useRenderIcon(Refresh)" @click="resetForm(formRef)"> {{ $t('buttons.reset') }}</el-button>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
|
||||||
|
<PureTableBar :columns="columns" title="${classDescription}" @fullscreen="tableRef.setAdaptive()" @refresh="onSearch">
|
||||||
|
<template #buttons>
|
||||||
|
<el-button :icon="useRenderIcon(AddFill)" type="primary" @click="onAdd"> {{ $t('addNew') }}</el-button>
|
||||||
|
|
||||||
|
<!-- 批量删除按钮 -->
|
||||||
|
<el-button v-show="deleteIds.length > 0" :icon="useRenderIcon(Delete)" type="danger" @click="onDeleteBatch">
|
||||||
|
{{ $t('delete_batches') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template v-slot="{ size, dynamicColumns }">
|
||||||
|
<pure-table
|
||||||
|
ref="tableRef"
|
||||||
|
:adaptiveConfig="{ offsetBottom: 96 }"
|
||||||
|
:columns="dynamicColumns"
|
||||||
|
:data="${lowercaseName}Store.datalist"
|
||||||
|
:header-cell-style="{ background: 'var(--el-fill-color-light)', color: 'var(--el-text-color-primary)' }"
|
||||||
|
:loading="${lowercaseName}Store.loading"
|
||||||
|
:size="size"
|
||||||
|
adaptive
|
||||||
|
align-whole="center"
|
||||||
|
border
|
||||||
|
highlight-current-row
|
||||||
|
row-key="id"
|
||||||
|
showOverflowTooltip
|
||||||
|
table-layout="auto"
|
||||||
|
:pagination="${lowercaseName}Store.pagination"
|
||||||
|
@page-size-change="onPageSizeChange"
|
||||||
|
@selection-change="onSelectionChange"
|
||||||
|
@page-current-change="onCurrentPageChange"
|
||||||
|
>
|
||||||
|
|
||||||
|
<template #createUser="{ row }">
|
||||||
|
<el-button v-show="row.createUser" link type="primary" @click="selectUserinfo(row.createUser)">
|
||||||
|
{{ row.createUsername }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #updateUser="{ row }">
|
||||||
|
<el-button v-show="row.updateUser" link type="primary" @click="selectUserinfo(row.updateUser)">
|
||||||
|
{{ row.updateUsername }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #operation="{ row }">
|
||||||
|
<el-button :icon="useRenderIcon(EditPen)" :size="size" class="reset-margin" link type="primary" @click="onUpdate(row)"> {{ $t('modify')
|
||||||
|
}}
|
||||||
|
</el-button>
|
||||||
|
<el-button :icon="useRenderIcon(AddFill)" :size="size" class="reset-margin" link type="primary" @click="onAdd"> {{ $t('addNew') }}
|
||||||
|
</el-button>
|
||||||
|
<!-- TODO 待完成 -->
|
||||||
|
<el-popconfirm :title="`${leftBrace}$t('delete')}${row.email}?`" @confirm="onDelete(row)">
|
||||||
|
<template #reference>
|
||||||
|
<el-button :icon="useRenderIcon(Delete)" :size="size" class="reset-margin" link type="primary">
|
||||||
|
{{ $t('delete') }}
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-popconfirm>
|
||||||
|
</template>
|
||||||
|
</pure-table>
|
||||||
|
</template>
|
||||||
|
</PureTableBar>
|
||||||
|
</div>
|
||||||
|
</template>
|
|
@ -0,0 +1,69 @@
|
||||||
|
import { defineStore } from 'pinia';
|
||||||
|
import { fetchAdd${originalName}, fetchDelete${originalName}, fetchGet${originalName}List, fetchUpdate${originalName} } from '${apiPath}';
|
||||||
|
import { pageSizes } from '@/enums/baseConstant';
|
||||||
|
import { storeMessage } from '@/utils/message';
|
||||||
|
import { storePagination } from '@/store/useStorePagination';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ${classTitle} Store
|
||||||
|
*/
|
||||||
|
export const use${originalName}Store = defineStore('${lowercaseName}Store', {
|
||||||
|
state() {
|
||||||
|
return {
|
||||||
|
// ${classTitle}列表
|
||||||
|
datalist: [],
|
||||||
|
// 查询表单
|
||||||
|
form: {
|
||||||
|
#foreach($item in $formList)
|
||||||
|
// $!{item.annotation}
|
||||||
|
$!{item.name}: undefined,
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
// 分页查询结果
|
||||||
|
pagination: {
|
||||||
|
currentPage: 1,
|
||||||
|
pageSize: 30,
|
||||||
|
total: 1,
|
||||||
|
pageSizes,
|
||||||
|
},
|
||||||
|
// 加载
|
||||||
|
loading: false,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
getters: {},
|
||||||
|
actions: {
|
||||||
|
/** 获取${classTitle} */
|
||||||
|
async get${originalName}List() {
|
||||||
|
// 整理请求参数
|
||||||
|
const data = { ...this.pagination, ...this.form };
|
||||||
|
delete data.pageSizes;
|
||||||
|
delete data.total;
|
||||||
|
delete data.background;
|
||||||
|
|
||||||
|
// 获取${classTitle}列表
|
||||||
|
const result = await fetchGet${originalName}List(data);
|
||||||
|
|
||||||
|
// 公共页面函数hook
|
||||||
|
const pagination = storePagination.bind(this);
|
||||||
|
return pagination(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 添加${classTitle} */
|
||||||
|
async add${originalName}(data: any) {
|
||||||
|
const result = await fetchAdd${originalName}(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 修改${classTitle} */
|
||||||
|
async update${originalName}(data: any) {
|
||||||
|
const result = await fetchUpdate${originalName}(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** 删除${classTitle} */
|
||||||
|
async delete${originalName}(data: any) {
|
||||||
|
const result = await fetchDelete${originalName}(data);
|
||||||
|
return storeMessage(result);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
|
@ -0,0 +1,12 @@
|
||||||
|
// 添加或者修改表单元素
|
||||||
|
export interface FormItemProps {
|
||||||
|
#foreach($field in $baseFieldList)
|
||||||
|
// $field.annotation
|
||||||
|
$field.name: $field.type;
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加或修改表单Props
|
||||||
|
export interface FormProps {
|
||||||
|
formInline: FormItemProps;
|
||||||
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
package cn.bunny;
|
||||||
|
|
||||||
|
|
||||||
|
import cn.bunny.config.DatabaseMetadataHolder;
|
||||||
|
import cn.bunny.entity.ColumnMetaData;
|
||||||
|
import cn.bunny.entity.TableMetaData;
|
||||||
|
import cn.bunny.utils.ConvertUtil;
|
||||||
|
import org.junit.jupiter.api.BeforeEach;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.sql.DatabaseMetaData;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
public class JDBCTest {
|
||||||
|
|
||||||
|
DatabaseMetaData metaData;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DatabaseMetadataHolder metadataHolder;
|
||||||
|
|
||||||
|
@BeforeEach
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
metaData = metadataHolder.getMetaData();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 获取表注释信息
|
||||||
|
*/
|
||||||
|
@Test
|
||||||
|
void testComment() throws SQLException {
|
||||||
|
String tableName = "sys_i18n";
|
||||||
|
|
||||||
|
TableMetaData tableMetaData;
|
||||||
|
|
||||||
|
ResultSet tables = metaData.getTables(null, null, tableName, new String[]{"TABLE"});
|
||||||
|
|
||||||
|
// 获取表的注释信息
|
||||||
|
if (tables.next()) {
|
||||||
|
String remarks = tables.getString("REMARKS" );
|
||||||
|
String tableCat = tables.getString("TABLE_CAT" );
|
||||||
|
String tableSchem = tables.getString("TABLE_SCHEM" );
|
||||||
|
String tableType = tables.getString("TABLE_TYPE" );
|
||||||
|
String typeCat = tables.getString("TYPE_CAT" );
|
||||||
|
String typeSchem = tables.getString("TYPE_SCHEM" );
|
||||||
|
String typeName = tables.getString("TYPE_NAME" );
|
||||||
|
String selfReferencingColName = tables.getString("SELF_REFERENCING_COL_NAME" );
|
||||||
|
String refGeneration = tables.getString("REF_GENERATION" );
|
||||||
|
|
||||||
|
tableMetaData = TableMetaData.builder()
|
||||||
|
.tableName(tableName)
|
||||||
|
.remarks(remarks)
|
||||||
|
.tableCat(tableCat)
|
||||||
|
.tableSchem(tableSchem)
|
||||||
|
.tableType(tableType)
|
||||||
|
.typeCat(typeCat)
|
||||||
|
.typeSchem(typeSchem)
|
||||||
|
.typeName(typeName)
|
||||||
|
.selfReferencingColName(selfReferencingColName)
|
||||||
|
.refGeneration(refGeneration)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
System.out.println(tableMetaData);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testColumnInfo() throws SQLException {
|
||||||
|
List<ColumnMetaData> columns = new ArrayList<>();
|
||||||
|
|
||||||
|
try (ResultSet columnsRs = metaData.getColumns(null, null, "sys_i18n" , null)) {
|
||||||
|
while (columnsRs.next()) {
|
||||||
|
ColumnMetaData column = new ColumnMetaData();
|
||||||
|
column.setColumnName(columnsRs.getString("COLUMN_NAME" ));
|
||||||
|
column.setFieldName(ConvertUtil.convertToFieldName(column.getColumnName()));
|
||||||
|
column.setJdbcType(columnsRs.getString("TYPE_NAME" ));
|
||||||
|
column.setJavaType(ConvertUtil.convertToJavaType(column.getJdbcType()));
|
||||||
|
column.setComment(columnsRs.getString("REMARKS" ));
|
||||||
|
|
||||||
|
columns.add(column);
|
||||||
|
System.out.println(column);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,37 @@
|
||||||
|
package cn.bunny.utils;
|
||||||
|
|
||||||
|
import cn.bunny.entity.ColumnMetaData;
|
||||||
|
import cn.bunny.entity.TableMetaData;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.boot.test.context.SpringBootTest;
|
||||||
|
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@SpringBootTest
|
||||||
|
class DbInfoUtilTest {
|
||||||
|
|
||||||
|
String tableName = "sys_i18n";
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DbInfoUtil dbInfoUtil;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void tableInfo() throws SQLException {
|
||||||
|
TableMetaData tableMetaData = dbInfoUtil.tableInfo(tableName);
|
||||||
|
System.out.println(tableMetaData);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void columnInfo() throws SQLException {
|
||||||
|
List<ColumnMetaData> columnMetaDataList = dbInfoUtil.columnInfo(tableName);
|
||||||
|
columnMetaDataList.forEach(System.out::println);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void dbInfo() throws SQLException {
|
||||||
|
TableMetaData tableMetaData = dbInfoUtil.dbInfo(tableName);
|
||||||
|
System.out.println(tableMetaData);
|
||||||
|
}
|
||||||
|
}
|
|
@ -37,8 +37,8 @@
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- mysql连接驱动 -->
|
<!-- mysql连接驱动 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- mysql连接池 -->
|
<!-- mysql连接池 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
|
|
12
pom.xml
12
pom.xml
|
@ -19,6 +19,7 @@
|
||||||
<module>common</module>
|
<module>common</module>
|
||||||
<module>dao</module>
|
<module>dao</module>
|
||||||
<module>service</module>
|
<module>service</module>
|
||||||
|
<module>common/generator-code</module>
|
||||||
</modules>
|
</modules>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
|
@ -27,7 +28,7 @@
|
||||||
<java.version>17</java.version>
|
<java.version>17</java.version>
|
||||||
<junit.version>3.8.1</junit.version>
|
<junit.version>3.8.1</junit.version>
|
||||||
<mybatis-plus.version>3.5.6</mybatis-plus.version>
|
<mybatis-plus.version>3.5.6</mybatis-plus.version>
|
||||||
<mysql.version>8.0.33</mysql.version>
|
<mysql.version>9.2.0</mysql.version>
|
||||||
<knife4j.version>4.5.0</knife4j.version>
|
<knife4j.version>4.5.0</knife4j.version>
|
||||||
<fastjson2.version>2.0.47</fastjson2.version>
|
<fastjson2.version>2.0.47</fastjson2.version>
|
||||||
<minio.version>8.5.17</minio.version>
|
<minio.version>8.5.17</minio.version>
|
||||||
|
@ -71,9 +72,14 @@
|
||||||
<version>${mybatis-plus.version}</version>
|
<version>${mybatis-plus.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- mysql -->
|
<!-- mysql -->
|
||||||
|
<!-- <dependency> -->
|
||||||
|
<!-- <groupId>com.mysql</groupId> -->
|
||||||
|
<!-- <artifactId>mysql-connector-java</artifactId> -->
|
||||||
|
<!-- <version>${mysql.version}</version> -->
|
||||||
|
<!-- </dependency> -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
<version>${mysql.version}</version>
|
<version>${mysql.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- mysql连接池 -->
|
<!-- mysql连接池 -->
|
||||||
|
|
|
@ -53,7 +53,6 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.1</version>
|
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
@ -119,14 +118,9 @@
|
||||||
|
|
||||||
<!-- mysql连接驱动 -->
|
<!-- mysql连接驱动 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>mysql</groupId>
|
<groupId>com.mysql</groupId>
|
||||||
<artifactId>mysql-connector-java</artifactId>
|
<artifactId>mysql-connector-j</artifactId>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- 多数据库源插件 -->
|
|
||||||
<!-- <dependency> -->
|
|
||||||
<!-- <groupId>com.baomidou</groupId> -->
|
|
||||||
<!-- <artifactId>dynamic-datasource-spring-boot3-starter</artifactId> -->
|
|
||||||
<!-- </dependency> -->
|
|
||||||
<!-- redis -->
|
<!-- redis -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.springframework.boot</groupId>
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
|
Loading…
Reference in New Issue