diff --git a/common/common-generator/src/main/resources/vms/server/controller.vm b/common/common-generator/src/main/resources/vms/server/controller.vm index 6421204..893074a 100644 --- a/common/common-generator/src/main/resources/vms/server/controller.vm +++ b/common/common-generator/src/main/resources/vms/server/controller.vm @@ -21,45 +21,45 @@ import java.util.List; * @author Bunny * @since ${date} */ -@Tag(name = "${classTitle}", description = "${classTitle}相关接口") +@Tag(name = "${classTitle}" , description = "${classTitle}相关接口" ) @RestController -@RequestMapping("admin/${lowercaseName}") +@RequestMapping("admin/${lowercaseName}" ) public class ${originalName}Controller { @Autowired private ${originalName}Service ${lowercaseName}Service; - @Operation(summary = "分页查询${classTitle}", description = "分页查询${classTitle}") - @GetMapping("get${originalName}List/{page}/{limit}") + @Operation(summary = "分页查询${classTitle}" , description = "分页查询${classTitle}" ) + @GetMapping("get${originalName}List/{page}/{limit}" ) public Mono>> get${originalName}List( - @Parameter(name = "page", description = "当前页", required = true) - @PathVariable("page") Integer page, - @Parameter(name = "limit", description = "每页记录数", required = true) - @PathVariable("limit") Integer limit, + @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}") + @Operation(summary = "添加${classTitle}" , description = "添加${classTitle}" ) + @PostMapping("add${originalName}" ) public Mono> 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}") + @Operation(summary = "更新${classTitle}" , description = "更新${classTitle}" ) + @PutMapping("update${originalName}" ) public Mono> 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}") + @Operation(summary = "删除${classTitle}" , description = "删除${classTitle}" ) + @DeleteMapping("delete${originalName}" ) public Mono> delete${originalName}(@RequestBody List ids) { ${lowercaseName}Service.delete${originalName}(ids); return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS)); } -} +} \ No newline at end of file diff --git a/common/generator-code/pom.xml b/common/generator-code/pom.xml new file mode 100644 index 0000000..d8e2180 --- /dev/null +++ b/common/generator-code/pom.xml @@ -0,0 +1,75 @@ + + 4.0.0 + + cn.bunny + auth-server-java + 0.0.1-SNAPSHOT + ../../pom.xml + + + generator-code + jar + + generator-code + https://maven.apache.org + + + UTF-8 + + + + + org.springframework.boot + spring-boot-starter-web + + + org.springframework.boot + spring-boot-starter-thymeleaf + + + + junit + junit + + + org.springframework.boot + spring-boot-starter-test + + + + org.xerial + sqlite-jdbc + 3.49.1.0 + + + com.mysql + mysql-connector-j + + + com.zaxxer + HikariCP + + + com.baomidou + dynamic-datasource-spring-boot3-starter + + + + + org.projectlombok + lombok + + + cn.hutool + hutool-all + + + + org.apache.velocity + velocity-engine-core + 2.3 + + + + diff --git a/common/generator-code/src/main/java/cn/bunny/GeneratorCodeMainApplication.java b/common/generator-code/src/main/java/cn/bunny/GeneratorCodeMainApplication.java new file mode 100644 index 0000000..670c0c8 --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/GeneratorCodeMainApplication.java @@ -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); + } +} diff --git a/common/generator-code/src/main/java/cn/bunny/config/DatabaseMetadataHolder.java b/common/generator-code/src/main/java/cn/bunny/config/DatabaseMetadataHolder.java new file mode 100644 index 0000000..d840633 --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/config/DatabaseMetadataHolder.java @@ -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(); + } + } +} \ No newline at end of file diff --git a/common/generator-code/src/main/java/cn/bunny/controller/IndexController.java b/common/generator-code/src/main/java/cn/bunny/controller/IndexController.java new file mode 100644 index 0000000..d7437ae --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/controller/IndexController.java @@ -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"; + } +} diff --git a/common/generator-code/src/main/java/cn/bunny/entity/ColumnMetaData.java b/common/generator-code/src/main/java/cn/bunny/entity/ColumnMetaData.java new file mode 100644 index 0000000..5558440 --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/entity/ColumnMetaData.java @@ -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; + +} \ No newline at end of file diff --git a/common/generator-code/src/main/java/cn/bunny/entity/TableMetaData.java b/common/generator-code/src/main/java/cn/bunny/entity/TableMetaData.java new file mode 100644 index 0000000..846aa6d --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/entity/TableMetaData.java @@ -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 columns; +} \ No newline at end of file diff --git a/common/generator-code/src/main/java/cn/bunny/service/IndexService.java b/common/generator-code/src/main/java/cn/bunny/service/IndexService.java new file mode 100644 index 0000000..c5f9734 --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/service/IndexService.java @@ -0,0 +1,5 @@ +package cn.bunny.service; + +public interface IndexService { + +} diff --git a/common/generator-code/src/main/java/cn/bunny/service/impl/IndexServiceImpl.java b/common/generator-code/src/main/java/cn/bunny/service/impl/IndexServiceImpl.java new file mode 100644 index 0000000..c3a7289 --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/service/impl/IndexServiceImpl.java @@ -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 { + +} diff --git a/common/generator-code/src/main/java/cn/bunny/utils/ConvertUtil.java b/common/generator-code/src/main/java/cn/bunny/utils/ConvertUtil.java new file mode 100644 index 0000000..0b2d09b --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/utils/ConvertUtil.java @@ -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(); + } +} diff --git a/common/generator-code/src/main/java/cn/bunny/utils/DbInfoUtil.java b/common/generator-code/src/main/java/cn/bunny/utils/DbInfoUtil.java new file mode 100644 index 0000000..5c637f4 --- /dev/null +++ b/common/generator-code/src/main/java/cn/bunny/utils/DbInfoUtil.java @@ -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 columnInfo(String tableName) throws SQLException { + DatabaseMetaData metaData = metadataHolder.getMetaData(); + List 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 = columnInfo(tableName); + TableMetaData tableMetaData = tableInfo(tableName); + + tableMetaData.setColumns(columnMetaData); + + return tableMetaData; + } +} diff --git a/common/generator-code/src/main/resources/application-dev.yml b/common/generator-code/src/main/resources/application-dev.yml new file mode 100644 index 0000000..3cabf82 --- /dev/null +++ b/common/generator-code/src/main/resources/application-dev.yml @@ -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" \ No newline at end of file diff --git a/common/generator-code/src/main/resources/application.yml b/common/generator-code/src/main/resources/application.yml new file mode 100644 index 0000000..c6955a7 --- /dev/null +++ b/common/generator-code/src/main/resources/application.yml @@ -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 diff --git a/common/generator-code/src/main/resources/banner.txt b/common/generator-code/src/main/resources/banner.txt new file mode 100644 index 0000000..f8a20fa --- /dev/null +++ b/common/generator-code/src/main/resources/banner.txt @@ -0,0 +1,10 @@ + _ _ +| |__ _ _ _ __ _ __ _ _ (_) __ ___ ____ _ +| '_ \| | | | '_ \| '_ \| | | | | |/ _` \ \ / / _` | +| |_) | |_| | | | | | | | |_| | | | (_| |\ V | (_| | +|_.__/ \__,_|_| |_|_| |_|\__, | _/ |\__,_| \_/ \__,_| + |___/ |__/ + +Service Name${spring.application.name} +SpringBoot Version: ${spring-boot.version}${spring-boot.formatted-version} +SpringActive:${spring.profiles.active} diff --git a/common/generator-code/src/main/resources/templates/index.html b/common/generator-code/src/main/resources/templates/index.html new file mode 100644 index 0000000..9d97bf5 --- /dev/null +++ b/common/generator-code/src/main/resources/templates/index.html @@ -0,0 +1,20 @@ + + + + + + 主页 + + +

666

+ + +
+ + +
+ + \ No newline at end of file diff --git a/common/generator-code/src/main/resources/vms/server/controller.vm b/common/generator-code/src/main/resources/vms/server/controller.vm new file mode 100644 index 0000000..893074a --- /dev/null +++ b/common/generator-code/src/main/resources/vms/server/controller.vm @@ -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; + +/** + *

+ * ${classTitle}表 前端控制器 + *

+ * + * @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>> 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> 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> 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> delete${originalName}(@RequestBody List ids) { + ${lowercaseName}Service.delete${originalName}(ids); + return Mono.just(Result.success(ResultCodeEnum.DELETE_SUCCESS)); + } +} \ No newline at end of file diff --git a/common/generator-code/src/main/resources/vms/server/mapper.vm b/common/generator-code/src/main/resources/vms/server/mapper.vm new file mode 100644 index 0000000..5029be8 --- /dev/null +++ b/common/generator-code/src/main/resources/vms/server/mapper.vm @@ -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; + +/** + *

+ * ${classTitle} Mapper 接口 + *

+ * + * @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 ids); +} diff --git a/common/generator-code/src/main/resources/vms/server/resourceMapper.vm b/common/generator-code/src/main/resources/vms/server/resourceMapper.vm new file mode 100644 index 0000000..2b1d789 --- /dev/null +++ b/common/generator-code/src/main/resources/vms/server/resourceMapper.vm @@ -0,0 +1,46 @@ + + + + + + + #foreach($field in $baseResultMaps) + + #end + + + + + $baseColumnList + + + + + + + + delete + from $tableName + where id in + + #{id} + + + + diff --git a/common/generator-code/src/main/resources/vms/server/service.vm b/common/generator-code/src/main/resources/vms/server/service.vm new file mode 100644 index 0000000..fafe220 --- /dev/null +++ b/common/generator-code/src/main/resources/vms/server/service.vm @@ -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; + +/** + *

+ * ${classTitle} 服务类 + *

+ * + * @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 ids); +} diff --git a/common/generator-code/src/main/resources/vms/server/serviceImpl.vm b/common/generator-code/src/main/resources/vms/server/serviceImpl.vm new file mode 100644 index 0000000..b418d2b --- /dev/null +++ b/common/generator-code/src/main/resources/vms/server/serviceImpl.vm @@ -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; + +/** + *

+ * ${classTitle} 服务实现类 + *

+ * + * @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 ids) { + baseMapper.deleteBatchIdsWithPhysics(ids); + } +} diff --git a/common/generator-code/src/main/resources/vms/web/api.vm b/common/generator-code/src/main/resources/vms/web/api.vm new file mode 100644 index 0000000..b49e6ae --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/api.vm @@ -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>('get', `${lowercaseName}/get${originalName}List/${data.currentPage}/${data.pageSize}`, { params: data }); +}; + +/** ${classDescription}---添加${classDescription} */ +export const fetchAdd${originalName} = (data: any) => { + return http.request>('post', '${lowercaseName}/add${originalName}', { data }); +}; + +/** ${classDescription}---更新${classDescription} */ +export const fetchUpdate${originalName} = (data: any) => { + return http.request>('put', '${lowercaseName}/update${originalName}', { data }); +}; + +/** ${classDescription}---删除${classDescription} */ +export const fetchDelete${originalName} = (data: any) => { + return http.request>('delete', '${lowercaseName}/delete${originalName}', { data }); +}; \ No newline at end of file diff --git a/common/generator-code/src/main/resources/vms/web/columns.vm b/common/generator-code/src/main/resources/vms/web/columns.vm new file mode 100644 index 0000000..712c6cc --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/columns.vm @@ -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 +({ + #foreach($field in $baseFieldList) + // $field.annotation + $field.name: [{ required: true, message: `$leftBrace$t('input')}$leftBrace$t('${field.name}')}`, trigger: 'blur' }], + #end + }); diff --git a/common/generator-code/src/main/resources/vms/web/dialog.vm b/common/generator-code/src/main/resources/vms/web/dialog.vm new file mode 100644 index 0000000..14324e0 --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/dialog.vm @@ -0,0 +1,36 @@ + + + diff --git a/common/generator-code/src/main/resources/vms/web/hook.vm b/common/generator-code/src/main/resources/vms/web/hook.vm new file mode 100644 index 0000000..f948132 --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/hook.vm @@ -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' }); + }); + }, + }); +}; \ No newline at end of file diff --git a/common/generator-code/src/main/resources/vms/web/index.vm b/common/generator-code/src/main/resources/vms/web/index.vm new file mode 100644 index 0000000..668241a --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/index.vm @@ -0,0 +1,121 @@ + + + diff --git a/common/generator-code/src/main/resources/vms/web/store.vm b/common/generator-code/src/main/resources/vms/web/store.vm new file mode 100644 index 0000000..7b504d6 --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/store.vm @@ -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); +}, +}, +}); diff --git a/common/generator-code/src/main/resources/vms/web/types.vm b/common/generator-code/src/main/resources/vms/web/types.vm new file mode 100644 index 0000000..07dab1f --- /dev/null +++ b/common/generator-code/src/main/resources/vms/web/types.vm @@ -0,0 +1,12 @@ +// 添加或者修改表单元素 +export interface FormItemProps { +#foreach($field in $baseFieldList) + // $field.annotation + $field.name: $field.type; +#end +} + +// 添加或修改表单Props +export interface FormProps { + formInline: FormItemProps; +} diff --git a/common/generator-code/src/test/java/cn/bunny/JDBCTest.java b/common/generator-code/src/test/java/cn/bunny/JDBCTest.java new file mode 100644 index 0000000..b35e433 --- /dev/null +++ b/common/generator-code/src/test/java/cn/bunny/JDBCTest.java @@ -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 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); + } + } + } +} diff --git a/common/generator-code/src/test/java/cn/bunny/utils/DbInfoUtilTest.java b/common/generator-code/src/test/java/cn/bunny/utils/DbInfoUtilTest.java new file mode 100644 index 0000000..43a6308 --- /dev/null +++ b/common/generator-code/src/test/java/cn/bunny/utils/DbInfoUtilTest.java @@ -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 columnMetaDataList = dbInfoUtil.columnInfo(tableName); + columnMetaDataList.forEach(System.out::println); + } + + @Test + void dbInfo() throws SQLException { + TableMetaData tableMetaData = dbInfoUtil.dbInfo(tableName); + System.out.println(tableMetaData); + } +} \ No newline at end of file diff --git a/common/pom.xml b/common/pom.xml index 360b4b0..ed72780 100644 --- a/common/pom.xml +++ b/common/pom.xml @@ -37,8 +37,8 @@ - mysql - mysql-connector-java + com.mysql + mysql-connector-j diff --git a/pom.xml b/pom.xml index 9cdebe2..a533efd 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ common dao service + common/generator-code @@ -27,7 +28,7 @@ 17 3.8.1 3.5.6 - 8.0.33 + 9.2.0 4.5.0 2.0.47 8.5.17 @@ -71,9 +72,14 @@ ${mybatis-plus.version} + + + + + - mysql - mysql-connector-java + com.mysql + mysql-connector-j ${mysql.version} diff --git a/service/pom.xml b/service/pom.xml index bde7825..2887ab6 100644 --- a/service/pom.xml +++ b/service/pom.xml @@ -53,7 +53,6 @@ junit junit - 3.8.1 org.springframework.boot @@ -119,14 +118,9 @@ - mysql - mysql-connector-java + com.mysql + mysql-connector-j - - - - - org.springframework.boot