Compare commits
3 Commits
429b425998
...
e42c6077fa
Author | SHA1 | Date |
---|---|---|
|
e42c6077fa | |
|
fb1edaddb3 | |
|
a8c2684fcc |
|
@ -1,72 +0,0 @@
|
|||
<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>common</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>generator-v1</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>common-utils</name>
|
||||
<url>https://maven.apache.org</url>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>cn.bunny</groupId>
|
||||
<artifactId>dao</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.fasterxml.jackson.datatype</groupId>
|
||||
<artifactId>jackson-datatype-jsr310</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.jsonwebtoken</groupId>
|
||||
<artifactId>jjwt</artifactId>
|
||||
</dependency>
|
||||
<!-- hutool -->
|
||||
<dependency>
|
||||
<groupId>cn.hutool</groupId>
|
||||
<artifactId>hutool-all</artifactId>
|
||||
</dependency>
|
||||
<!-- mysql连接驱动 -->
|
||||
<dependency>
|
||||
<groupId>com.mysql</groupId>
|
||||
<artifactId>mysql-connector-j</artifactId>
|
||||
</dependency>
|
||||
<!-- mysql连接池 -->
|
||||
<dependency>
|
||||
<groupId>com.zaxxer</groupId>
|
||||
<artifactId>HikariCP</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>javax.xml.bind</groupId>
|
||||
<artifactId>jaxb-api</artifactId>
|
||||
<version>2.1</version>
|
||||
</dependency>
|
||||
<!-- 数据库代码生成器 - 新版 -->
|
||||
<dependency>
|
||||
<groupId>com.baomidou</groupId>
|
||||
<artifactId>mybatis-plus-generator</artifactId>
|
||||
<version>3.5.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.velocity</groupId>
|
||||
<artifactId>velocity-engine-core</artifactId>
|
||||
<version>2.3</version>
|
||||
</dependency>
|
||||
<!-- 驼峰命名互转 -->
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
<version>33.3.0-jre</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
|
@ -1,30 +0,0 @@
|
|||
package cn.bunny.common.generator.entity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@ApiModel(value = "BaseEntity对象", description = "生成类基础内容")
|
||||
public class BaseField {
|
||||
@ApiModelProperty("字段名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("注释内容")
|
||||
private String annotation;
|
||||
|
||||
@ApiModelProperty("TS类型")
|
||||
private String type;
|
||||
|
||||
@ApiModelProperty("是否必须参数")
|
||||
private Boolean require;
|
||||
|
||||
@ApiModelProperty("是否必须参数消息内容")
|
||||
private String requireMessage;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.bunny.common.generator.entity;
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@Schema(name = "BaseResultMap对象", title = "数据库基础字段返回映射", description = "数据库基础字段返回映射")
|
||||
public class BaseResultMap {
|
||||
|
||||
@Schema(name = "column", title = "数据库字段")
|
||||
private String column;
|
||||
|
||||
@Schema(name = "property", title = "实体类字段")
|
||||
private String property;
|
||||
}
|
|
@ -1,21 +0,0 @@
|
|||
package cn.bunny.common.generator.entity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@ApiModel(value = "ColumnsField对象", description = "columns列字段名称")
|
||||
public class ColumnsField {
|
||||
@ApiModelProperty("列字段名称")
|
||||
private String name;
|
||||
|
||||
@ApiModelProperty("列字段值")
|
||||
private String value;
|
||||
}
|
|
@ -1,26 +0,0 @@
|
|||
package cn.bunny.common.generator.entity;
|
||||
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
@NoArgsConstructor
|
||||
@Builder
|
||||
@ApiModel(value = "StoreTypeField对象", description = "仓库类型生成内容")
|
||||
public class StoreTypeField {
|
||||
|
||||
private List<BaseField> baseFieldList;
|
||||
|
||||
@ApiModelProperty("接口名称")
|
||||
private String interfaceName;
|
||||
|
||||
@ApiModelProperty("接口注释内容")
|
||||
private String interfaceAnnotation;
|
||||
}
|
|
@ -1,76 +0,0 @@
|
|||
package cn.bunny.common.generator.generator;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.OutputFile;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class AdminCodeGenerator {
|
||||
// 数据连接
|
||||
public static final String sqlHost = "jdbc:mysql://192.168.3.98:3304/auth_admin?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
|
||||
// 作者名称
|
||||
public static final String author = "Bunny";
|
||||
// 公共路径
|
||||
// public static final String outputDir = "D:\\MyFolder\\auth-admin\\auth-server-java\\service";
|
||||
public static final String outputDir = "D:\\Project\\web\\PC\\auth\\auth-server-java\\service";
|
||||
// 实体类名称
|
||||
public static final String entity = "Bunny";
|
||||
|
||||
public static void main(String[] args) {
|
||||
Generation("sys_message_received");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表名生成相应结构代码
|
||||
*
|
||||
* @param tableName 表名
|
||||
*/
|
||||
public static void Generation(String... tableName) {
|
||||
// 修改数据库路径、账户、密码
|
||||
FastAutoGenerator.create(sqlHost, "root", "02120212")
|
||||
.globalConfig(builder -> {
|
||||
// 添加作者名称
|
||||
builder.author(author)
|
||||
// 启用swagger
|
||||
.enableSwagger()
|
||||
// 指定输出目录
|
||||
.outputDir(outputDir + "/src/main/java");
|
||||
})
|
||||
.packageConfig(builder -> builder.entity(entity)// 实体类包名
|
||||
// 父包名。如果为空,将下面子包名必须写全部, 否则就只需写子包名
|
||||
.parent("cn.bunny.services")
|
||||
.controller("controller")// 控制层包名
|
||||
.mapper("mapper")// mapper层包名
|
||||
.service("service")// service层包名
|
||||
.serviceImpl("service.impl")// service实现类包名
|
||||
// 自定义mapper.xml文件输出目录
|
||||
.pathInfo(Collections.singletonMap(OutputFile.xml, outputDir + "/src/main/resources/mapper")))
|
||||
.strategyConfig(builder -> {
|
||||
// 设置要生成的表名
|
||||
builder.addInclude(tableName)
|
||||
.addTablePrefix("sys_", "v_", "log_")
|
||||
.entityBuilder()
|
||||
.enableLombok()
|
||||
.enableChainModel()
|
||||
.naming(NamingStrategy.underline_to_camel)// 数据表映射实体命名策略:默认下划线转驼峰underline_to_camel
|
||||
.columnNaming(NamingStrategy.underline_to_camel)// 表字段映射实体属性命名规则:默认null,不指定按照naming执行
|
||||
.idType(IdType.AUTO)// 添加全局主键类型
|
||||
.formatFileName("%s")// 格式化实体名称,%s取消首字母I,
|
||||
.mapperBuilder()
|
||||
.mapperAnnotation(Mapper.class)// 开启mapper注解
|
||||
.enableBaseResultMap()// 启用xml文件中的BaseResultMap 生成
|
||||
.enableBaseColumnList()// 启用xml文件中的BaseColumnList
|
||||
.formatMapperFileName("%sMapper")// 格式化Dao类名称
|
||||
.formatXmlFileName("%sMapper")// 格式化xml文件名称
|
||||
.serviceBuilder()
|
||||
.formatServiceFileName("%sService")// 格式化 service 接口文件名称
|
||||
.formatServiceImplFileName("%sServiceImpl")// 格式化 service 接口文件名称
|
||||
.controllerBuilder()
|
||||
.enableRestStyle();
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
}
|
|
@ -1,75 +0,0 @@
|
|||
package cn.bunny.common.generator.generator;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.OutputFile;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
public class I18nCodeGenerator {
|
||||
// 数据连接
|
||||
public static final String sqlHost = "jdbc:mysql://106.15.251.123:3305/bunny_docs_i18n?serverTimezone=GMT%2B8&useSSL=false&characterEncoding=utf-8&allowPublicKeyRetrieval=true";
|
||||
// 作者名称
|
||||
public static final String author = "Bunny";
|
||||
// 公共路径
|
||||
public static final String outputDir = "D:\\MyFolder\\Bunny\\BunnyBBS\\BunnyBBS-server-admin\\service";
|
||||
// 实体类名称
|
||||
public static final String entity = "Bunny";
|
||||
|
||||
public static void main(String[] args) {
|
||||
Generation("language");
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据表名生成相应结构代码
|
||||
*
|
||||
* @param tableName 表名
|
||||
*/
|
||||
public static void Generation(String... tableName) {
|
||||
FastAutoGenerator.create(sqlHost, "root", "02120212")
|
||||
.globalConfig(builder -> {
|
||||
// 添加作者名称
|
||||
builder.author(author)
|
||||
// 启用swagger
|
||||
.enableSwagger()
|
||||
// 指定输出目录
|
||||
.outputDir(outputDir + "/src/main/java");
|
||||
})
|
||||
.packageConfig(builder -> {
|
||||
builder.entity(entity)// 实体类包名
|
||||
.parent("cn.bunny.service.admin")
|
||||
.controller("controller.i18n")// 控制层包名
|
||||
.mapper("mapper.i18n")// mapper层包名
|
||||
.service("service.i18n")// service层包名
|
||||
.serviceImpl("service.i18n.impl")// service实现类包名
|
||||
// 自定义mapper.xml文件输出目录
|
||||
.pathInfo(Collections.singletonMap(OutputFile.xml, outputDir + "/src/main/resources/mapper/i18n"));
|
||||
})
|
||||
.strategyConfig(builder -> {
|
||||
// 设置要生成的表名
|
||||
builder.addInclude(tableName)
|
||||
//.addTablePrefix("sys_")// 设置表前缀过滤
|
||||
.entityBuilder()
|
||||
.enableLombok()
|
||||
.enableChainModel()
|
||||
.naming(NamingStrategy.underline_to_camel)// 数据表映射实体命名策略:默认下划线转驼峰underline_to_camel
|
||||
.columnNaming(NamingStrategy.underline_to_camel)// 表字段映射实体属性命名规则:默认null,不指定按照naming执行
|
||||
.idType(IdType.AUTO)// 添加全局主键类型
|
||||
.formatFileName("%s")// 格式化实体名称,%s取消首字母I,
|
||||
.mapperBuilder()
|
||||
.mapperAnnotation(Mapper.class)// 开启mapper注解
|
||||
.enableBaseResultMap()// 启用xml文件中的BaseResultMap 生成
|
||||
.enableBaseColumnList()// 启用xml文件中的BaseColumnList
|
||||
.formatMapperFileName("%sMapper")// 格式化Dao类名称
|
||||
.formatXmlFileName("%sMapper")// 格式化xml文件名称
|
||||
.serviceBuilder()
|
||||
.formatServiceFileName("%sService")// 格式化 service 接口文件名称
|
||||
.formatServiceImplFileName("%sServiceImpl")// 格式化 service 接口文件名称
|
||||
.controllerBuilder()
|
||||
.enableRestStyle();
|
||||
})
|
||||
.execute();
|
||||
}
|
||||
}
|
|
@ -1,275 +0,0 @@
|
|||
package cn.bunny.common.generator.generator;
|
||||
|
||||
import cn.bunny.common.generator.entity.BaseField;
|
||||
import cn.bunny.common.generator.entity.BaseResultMap;
|
||||
import cn.bunny.common.generator.utils.GeneratorCodeUtils;
|
||||
import cn.bunny.dao.dto.system.user.AdminUserAddDto;
|
||||
import cn.bunny.dao.dto.system.user.AdminUserDto;
|
||||
import cn.bunny.dao.dto.system.user.AdminUserUpdateDto;
|
||||
import cn.bunny.dao.entity.system.AdminUser;
|
||||
import cn.bunny.dao.vo.system.user.AdminUserVo;
|
||||
import com.baomidou.mybatisplus.annotation.TableName;
|
||||
import com.google.common.base.CaseFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import jakarta.validation.constraints.NotBlank;
|
||||
import jakarta.validation.constraints.NotNull;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.time.LocalDateTime;
|
||||
import java.time.format.DateTimeFormatter;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
/**
|
||||
* * 代码生成器入口点
|
||||
*/
|
||||
@Service
|
||||
public class WebGeneratorCode {
|
||||
// 公共路径
|
||||
// public static String commonPath = "D:\\Project\\web\\PC\\financial\\financial-web\\src";
|
||||
public static String commonPath = "D:\\MyFolder\\financial\\financial-web\\src";
|
||||
// 生成API请求路径
|
||||
public static String apiPath = commonPath + "\\api\\v1\\financial\\";
|
||||
// 生成vue路径
|
||||
public static String vuePath = commonPath + "\\views\\financial\\";
|
||||
// 生成仓库路径
|
||||
public static String storePath = commonPath + "\\store\\financial\\";
|
||||
// 后端controller
|
||||
public static String controllerPath = "D:\\MyFolder\\financial\\financial-server\\service\\src\\main\\java\\cn\\bunny\\services\\controller\\financial\\";
|
||||
public static String servicePath = "D:\\MyFolder\\financial\\financial-server\\service\\src\\main\\java\\cn\\bunny\\services\\service\\financial\\";
|
||||
public static String serviceImplPath = "D:\\MyFolder\\financial\\financial-server\\service\\src\\main\\java\\cn\\bunny\\services\\service\\financial\\impl\\";
|
||||
public static String mapperPath = "D:\\MyFolder\\financial\\financial-server\\service\\src\\main\\java\\cn\\bunny\\services\\mapper\\financial\\";
|
||||
public static String resourceMapperPath = "D:\\MyFolder\\financial\\financial-server\\service\\src\\main\\resources\\mapper\\financial\\";
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Class<?> originalClass = AdminUser.class;
|
||||
Class<?> dtoClass = AdminUserDto.class;
|
||||
Class<?> addDtoClass = AdminUserAddDto.class;
|
||||
Class<?> updateDtoClass = AdminUserUpdateDto.class;
|
||||
Class<?> voClass = AdminUserVo.class;
|
||||
|
||||
// 设置velocity资源加载器
|
||||
Properties prop = new Properties();
|
||||
prop.put("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
|
||||
Velocity.init(prop);
|
||||
// 创建Velocity容器
|
||||
VelocityContext context = new VelocityContext();
|
||||
|
||||
// 原始类名称
|
||||
String originalName = originalClass.getSimpleName();
|
||||
// 转成开头小写类名称,作为文件名
|
||||
String lowercaseName = originalName.substring(0, 1).toLowerCase() + originalName.substring(1);
|
||||
// 转成中划线,做vue命名使用
|
||||
String lowerHyphen = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, originalName);
|
||||
// 生成字段xxx管理
|
||||
String classDescription = originalClass.getAnnotation(Schema.class).description();
|
||||
// 类注解标题
|
||||
String classTitle = originalClass.getAnnotation(Schema.class).title();
|
||||
|
||||
context.put("originalName", originalName);
|
||||
context.put("lowercaseName", lowercaseName);
|
||||
context.put("lowerHyphen", lowerHyphen);
|
||||
context.put("classDescription", classDescription);
|
||||
context.put("classTitle", classTitle);
|
||||
context.put("leftBrace", "${");
|
||||
context.put("date", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
||||
|
||||
// 生成前端内容
|
||||
generatorWebCode(dtoClass, addDtoClass, context);
|
||||
|
||||
// 生成后端
|
||||
generatorServerCode(originalClass, dtoClass, voClass, context);
|
||||
|
||||
// 写入文件
|
||||
writeFiles(lowercaseName, lowerHyphen, originalName, context);
|
||||
}
|
||||
|
||||
/**
|
||||
* * web端生成字段
|
||||
*/
|
||||
public static void generatorWebCode(Class<?> dtoClass, Class<?> addDtoClass, VelocityContext context) {
|
||||
// 生成 Store 中 form 表单内容
|
||||
List<BaseField> formList = Arrays.stream(dtoClass.getDeclaredFields())
|
||||
.filter(field -> !field.getName().equals("id"))
|
||||
.map(field -> BaseField.builder().name(field.getName()).annotation(field.getAnnotation(Schema.class).title()).build())
|
||||
.toList();
|
||||
|
||||
// 添加表单字段值
|
||||
List<String> addFormList = Arrays.stream(addDtoClass.getDeclaredFields()).map(Field::getName).toList();
|
||||
|
||||
// 是否必须字段设置
|
||||
List<BaseField> baseFieldList = Arrays.stream(addDtoClass.getDeclaredFields()).map(field -> {
|
||||
try {
|
||||
String message = "";
|
||||
boolean hasMessage = false;
|
||||
// 验证消息
|
||||
NotBlank messageAnnotation = field.getAnnotation(NotBlank.class);
|
||||
if (messageAnnotation != null) {
|
||||
message = messageAnnotation.message();
|
||||
hasMessage = StringUtils.hasText(message);
|
||||
if (!hasMessage) message = field.getAnnotation(NotNull.class).message();
|
||||
}
|
||||
|
||||
|
||||
// 设置基础字段注解和是否必填项
|
||||
BaseField baseField = new BaseField();
|
||||
baseField.setName(field.getName());
|
||||
baseField.setType(baseField.getType());
|
||||
baseField.setAnnotation(field.getAnnotation(Schema.class).title());
|
||||
baseField.setType(GeneratorCodeUtils.convertJavaTypeToTypeScript(field.getType()));
|
||||
baseField.setRequire(hasMessage);
|
||||
if (hasMessage) baseField.setRequireMessage(message);
|
||||
|
||||
return baseField;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}).toList();
|
||||
|
||||
// 生成查询表单字段
|
||||
context.put("formList", formList);
|
||||
context.put("addFormList", addFormList);
|
||||
context.put("baseFieldList", baseFieldList);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成后端内容
|
||||
*/
|
||||
public static void generatorServerCode(Class<?> originalClass, Class<?> dtoClass, Class<?> voClass, VelocityContext context) {
|
||||
Field[] superFields = originalClass.getSuperclass().getDeclaredFields();
|
||||
Field[] declaredFields = originalClass.getDeclaredFields();
|
||||
Field[] mergedArray = new Field[superFields.length + declaredFields.length];
|
||||
System.arraycopy(superFields, 0, mergedArray, 0, superFields.length);
|
||||
System.arraycopy(declaredFields, 0, mergedArray, superFields.length, declaredFields.length);
|
||||
|
||||
// 添加BaseResultMap
|
||||
List<BaseResultMap> baseResultMaps = Arrays.stream(mergedArray).map(field -> {
|
||||
// 转成下划线
|
||||
String fieldName = field.getName();
|
||||
String lowerUnderscore = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, fieldName);
|
||||
|
||||
BaseResultMap baseResultMap = new BaseResultMap();
|
||||
baseResultMap.setColumn(lowerUnderscore);
|
||||
baseResultMap.setProperty(fieldName);
|
||||
return baseResultMap;
|
||||
}).toList();
|
||||
|
||||
// 分页查询内容
|
||||
List<BaseResultMap> pageQueryMap = Arrays.stream(dtoClass.getDeclaredFields()).map(field -> {
|
||||
String name = field.getName();
|
||||
String column = CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, name);
|
||||
|
||||
return BaseResultMap.builder().column(column).property(name).build();
|
||||
}).toList();
|
||||
|
||||
// 生层Base_Column_List
|
||||
String baseColumnList = Stream.of(mergedArray)
|
||||
.map(field -> CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, field.getName()))
|
||||
.collect(Collectors.joining(", "));
|
||||
|
||||
// 表名
|
||||
String tableName = originalClass.getAnnotation(TableName.class).value();
|
||||
|
||||
context.put("baseResultMaps", baseResultMaps);
|
||||
context.put("type", originalClass.getName());
|
||||
context.put("voClassType", voClass.getName());
|
||||
context.put("baseColumnList", baseColumnList);
|
||||
context.put("tableName", tableName);
|
||||
context.put("pageQueryMap", pageQueryMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* * 写入文件
|
||||
*/
|
||||
public static void writeFiles(String lowercaseName, String lowerHyphen, String originalName, VelocityContext context) throws IOException {
|
||||
context.put("apiPath", GeneratorCodeUtils.ReplacePathHandle(apiPath) + lowercaseName);
|
||||
context.put("storePath", GeneratorCodeUtils.ReplacePathHandle(storePath) + lowercaseName);
|
||||
context.put("typesPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/types");
|
||||
context.put("hookPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/hooks");
|
||||
context.put("columnsPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/utils/columns");
|
||||
context.put("dialogPath", GeneratorCodeUtils.ReplacePathHandle(vuePath) + lowercaseName + "/" + lowerHyphen + "-dialog.vue");
|
||||
|
||||
// 写入api模板
|
||||
Template apiTemplate = Velocity.getTemplate("vms/web/api.vm", "UTF-8");
|
||||
FileWriter apiTemplateFileWriter = new FileWriter(apiPath + lowercaseName + ".ts");
|
||||
apiTemplate.merge(context, apiTemplateFileWriter);
|
||||
apiTemplateFileWriter.close();
|
||||
|
||||
// 写入弹窗模板
|
||||
Template dialogTemplate = Velocity.getTemplate("vms/web/dialog.vm", "UTF-8");
|
||||
FileWriter dialogTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\" + lowerHyphen + "-dialog.vue");
|
||||
dialogTemplate.merge(context, dialogTemplateFileWriter);
|
||||
dialogTemplateFileWriter.close();
|
||||
|
||||
// 写入hook模板
|
||||
Template hookTemplate = Velocity.getTemplate("vms/web/hook.vm", "UTF-8");
|
||||
FileWriter hookTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\utils\\hooks.ts");
|
||||
hookTemplate.merge(context, hookTemplateFileWriter);
|
||||
hookTemplateFileWriter.close();
|
||||
|
||||
// 写入hook模板
|
||||
Template storeTemplate = Velocity.getTemplate("vms/web/store.vm", "UTF-8");
|
||||
FileWriter storeTemplateFileWriter = new FileWriter(storePath + "\\" + lowercaseName + ".ts");
|
||||
storeTemplate.merge(context, storeTemplateFileWriter);
|
||||
storeTemplateFileWriter.close();
|
||||
|
||||
// 写入types模板
|
||||
Template typesTemplate = Velocity.getTemplate("vms/web/types.vm", "UTF-8");
|
||||
FileWriter typesTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\utils\\types.ts");
|
||||
typesTemplate.merge(context, typesTemplateFileWriter);
|
||||
typesTemplateFileWriter.close();
|
||||
|
||||
// 写入index模板
|
||||
Template indexTemplate = Velocity.getTemplate("vms/web/index.vm", "UTF-8");
|
||||
FileWriter indexTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\index.vue");
|
||||
indexTemplate.merge(context, indexTemplateFileWriter);
|
||||
indexTemplateFileWriter.close();
|
||||
|
||||
// 写入columns模板
|
||||
Template columnsTemplate = Velocity.getTemplate("vms/web/columns.vm", "UTF-8");
|
||||
FileWriter columnsTemplateFileWriter = new FileWriter(vuePath + lowercaseName + "\\utils\\columns.ts");
|
||||
columnsTemplate.merge(context, columnsTemplateFileWriter);
|
||||
columnsTemplateFileWriter.close();
|
||||
|
||||
// 写入controller模板
|
||||
Template controllerTemplate = Velocity.getTemplate("vms/server/controller.vm", "UTF-8");
|
||||
FileWriter controllerTemplateFileWriter = new FileWriter(controllerPath + originalName + "Controller.java");
|
||||
controllerTemplate.merge(context, controllerTemplateFileWriter);
|
||||
controllerTemplateFileWriter.close();
|
||||
|
||||
// 写入servicePath模板
|
||||
Template servicePathTemplate = Velocity.getTemplate("vms/server/service.vm", "UTF-8");
|
||||
FileWriter servicePathTemplateFileWriter = new FileWriter(servicePath + originalName + "Service.java");
|
||||
servicePathTemplate.merge(context, servicePathTemplateFileWriter);
|
||||
servicePathTemplateFileWriter.close();
|
||||
|
||||
// 写入serviceImplPath模板
|
||||
Template serviceImplPathTemplate = Velocity.getTemplate("vms/server/serviceImpl.vm", "UTF-8");
|
||||
FileWriter serviceImplPathTemplateFileWriter = new FileWriter(serviceImplPath + originalName + "ServiceImpl.java");
|
||||
serviceImplPathTemplate.merge(context, serviceImplPathTemplateFileWriter);
|
||||
serviceImplPathTemplateFileWriter.close();
|
||||
|
||||
// 写入serviceImplPath模板
|
||||
Template mapperPathTemplate = Velocity.getTemplate("vms/server/mapper.vm", "UTF-8");
|
||||
FileWriter mapperPathTemplateFileWriter = new FileWriter(mapperPath + originalName + "Mapper.java");
|
||||
mapperPathTemplate.merge(context, mapperPathTemplateFileWriter);
|
||||
mapperPathTemplateFileWriter.close();
|
||||
|
||||
// 写入resourceMapperPath模板
|
||||
Template resourceMapperPathTemplate = Velocity.getTemplate("vms/server/resourceMapper.vm", "UTF-8");
|
||||
FileWriter resourceMapperPathTemplateFileWriter = new FileWriter(resourceMapperPath + originalName + "Mapper.xml");
|
||||
resourceMapperPathTemplate.merge(context, resourceMapperPathTemplateFileWriter);
|
||||
resourceMapperPathTemplateFileWriter.close();
|
||||
}
|
||||
}
|
||||
|
|
@ -1,98 +0,0 @@
|
|||
package cn.bunny.common.generator.utils;
|
||||
|
||||
import cn.bunny.common.generator.entity.BaseField;
|
||||
import cn.bunny.common.generator.entity.StoreTypeField;
|
||||
import io.swagger.annotations.ApiModel;
|
||||
import io.swagger.annotations.ApiModelProperty;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
import static cn.bunny.common.generator.generator.WebGeneratorCode.commonPath;
|
||||
|
||||
|
||||
public class GeneratorCodeUtils {
|
||||
public static String convertJavaTypeToTypeScript(Class<?> javaType) {
|
||||
if (javaType.isPrimitive()) {
|
||||
return getPrimitiveTypeMapping(javaType.getSimpleName());
|
||||
} else if (javaType.isArray()) {
|
||||
return "Array<" + convertJavaTypeToTypeScript(javaType.getComponentType()) + ">";
|
||||
} else if (javaType.equals(List.class) || javaType.equals(Set.class) || javaType.equals(Map.class)) {
|
||||
return "any";
|
||||
} else {
|
||||
return getPrimitiveTypeMapping(javaType.getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* * 将Java类型转成JS/TS类型
|
||||
*
|
||||
* @param primitiveType Java的类型
|
||||
* @return 转换后的类型
|
||||
*/
|
||||
private static String getPrimitiveTypeMapping(String primitiveType) {
|
||||
return switch (primitiveType) {
|
||||
case "int", "long", "short", "byte", "float", "double", "Byte", "Integer", "Long", "Float", "Double" ->
|
||||
"number";
|
||||
case "boolean", "Boolean" -> "boolean";
|
||||
case "char", "Character", "String" -> "string";
|
||||
default -> "any";
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* * 生成返回对象类字段
|
||||
* 返回字段包含:TS接口名称,TS接口名称注释,TS接口字段、TS字段类型、TS字段注释、TS字段注释解释
|
||||
*
|
||||
* @param voClass 返回对象类
|
||||
* @return 整理好返回字段
|
||||
*/
|
||||
public static StoreTypeField handleGenerator(Class<?> voClass) {
|
||||
// 类的详细信息
|
||||
String interfaceAnnotation = voClass.getAnnotation(ApiModel.class).description();
|
||||
|
||||
// 字段
|
||||
List<Field> fields = new ArrayList<>(Arrays.stream(voClass.getDeclaredFields()).toList());
|
||||
List<Field> superList = Arrays.stream(voClass.getSuperclass().getDeclaredFields()).toList();
|
||||
fields.addAll(superList);
|
||||
|
||||
List<BaseField> list = fields.stream()
|
||||
.map(field -> {
|
||||
field.setAccessible(true);
|
||||
|
||||
// 将类型转成TS
|
||||
Class<?> type = field.getType();
|
||||
String convertJavaTypeToTypeScript = GeneratorCodeUtils.convertJavaTypeToTypeScript(type);
|
||||
|
||||
// 注释内容
|
||||
String annotationName = Objects.requireNonNull(field.getAnnotation(ApiModelProperty.class).name());
|
||||
// 注释解释
|
||||
String value = field.getAnnotation(ApiModelProperty.class).value();
|
||||
|
||||
// 构建返回内容
|
||||
BaseField storeTypeField = new BaseField();
|
||||
storeTypeField.setName(field.getName());
|
||||
storeTypeField.setAnnotation(annotationName);
|
||||
storeTypeField.setType(convertJavaTypeToTypeScript);
|
||||
|
||||
return storeTypeField;
|
||||
}).toList();
|
||||
|
||||
StoreTypeField storeTypeField = new StoreTypeField();
|
||||
storeTypeField.setBaseFieldList(list);
|
||||
storeTypeField.setInterfaceName(voClass.getSimpleName());
|
||||
storeTypeField.setInterfaceAnnotation(interfaceAnnotation);
|
||||
|
||||
return storeTypeField;
|
||||
}
|
||||
|
||||
/**
|
||||
* * 通用处理路径内容
|
||||
*
|
||||
* @param path 路径
|
||||
* @return 处理好的路径
|
||||
*/
|
||||
public static String ReplacePathHandle(String path) {
|
||||
return "@" + path.replace(commonPath, "").replace("\\", "/");
|
||||
}
|
||||
}
|
|
@ -1,65 +0,0 @@
|
|||
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));
|
||||
}
|
||||
}
|
|
@ -1,35 +0,0 @@
|
|||
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);
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?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>
|
|
@ -1,49 +0,0 @@
|
|||
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);
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
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);
|
||||
}
|
||||
}
|
|
@ -1,22 +0,0 @@
|
|||
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 });
|
||||
};
|
|
@ -1,27 +0,0 @@
|
|||
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
|
||||
});
|
|
@ -1,36 +0,0 @@
|
|||
<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>
|
|
@ -1,130 +0,0 @@
|
|||
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' });
|
||||
});
|
||||
},
|
||||
});
|
||||
};
|
|
@ -1,121 +0,0 @@
|
|||
<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>
|
|
@ -1,69 +0,0 @@
|
|||
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);
|
||||
},
|
||||
},
|
||||
});
|
|
@ -1,12 +0,0 @@
|
|||
// 添加或者修改表单元素
|
||||
export interface FormItemProps {
|
||||
#foreach($field in $baseFieldList)
|
||||
// $field.annotation
|
||||
$field.name: $field.type;
|
||||
#end
|
||||
}
|
||||
|
||||
// 添加或修改表单Props
|
||||
export interface FormProps {
|
||||
formInline: FormItemProps;
|
||||
}
|
|
@ -1,18 +0,0 @@
|
|||
<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/maven-v4_0_0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>cn.bunny</groupId>
|
||||
<artifactId>auth-server-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>common</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>common Maven Webapp</name>
|
||||
<url>https://maven.apache.org</url>
|
||||
<modules>
|
||||
<module>generator-code</module>
|
||||
<module>generator-v1</module>
|
||||
</modules>
|
||||
</project>
|
|
@ -5,7 +5,6 @@
|
|||
<groupId>cn.bunny</groupId>
|
||||
<artifactId>auth-server-java</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<relativePath>../../pom.xml</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>generator-code</artifactId>
|
Before Width: | Height: | Size: 17 KiB After Width: | Height: | Size: 17 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
2
pom.xml
2
pom.xml
|
@ -16,7 +16,7 @@
|
|||
<description>bunny-template</description>
|
||||
|
||||
<modules>
|
||||
<module>common</module>
|
||||
<module>generator-code</module>
|
||||
<module>dao</module>
|
||||
<module>service</module>
|
||||
</modules>
|
||||
|
|
|
@ -17,7 +17,6 @@ import jakarta.validation.Valid;
|
|||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import reactor.core.publisher.Mono;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
@ -40,9 +39,9 @@ public class I18nController {
|
|||
|
||||
@Operation(summary = "获取多语言内容", description = "获取多语言内容")
|
||||
@GetMapping("getI18n")
|
||||
public Mono<Result<Map<String, Object>>> getI18n() {
|
||||
public Result<Map<String, Object>> getI18n() {
|
||||
Map<String, Object> vo = i18nService.getI18n();
|
||||
return Mono.just(Result.success(vo));
|
||||
return Result.success(vo);
|
||||
}
|
||||
|
||||
@Operation(summary = "获取管理多语言列", description = "获取管理多语言列")
|
||||
|
|
|
@ -155,26 +155,23 @@ public class I18nServiceImpl extends ServiceImpl<I18nMapper, I18n> implements I1
|
|||
@Override
|
||||
public ResponseEntity<byte[]> downloadI18n() {
|
||||
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
|
||||
ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream);
|
||||
try (ZipOutputStream zipOutputStream = new ZipOutputStream(byteArrayOutputStream)) {
|
||||
|
||||
// 查找默认语言内容
|
||||
List<I18n> i18nList = list();
|
||||
HashMap<String, Object> hashMap = I18nUtil.getMap(i18nList);
|
||||
// 查找默认语言内容
|
||||
List<I18n> i18nList = list();
|
||||
HashMap<String, Object> hashMap = I18nUtil.getMap(i18nList);
|
||||
|
||||
hashMap.forEach((k, v) -> {
|
||||
try {
|
||||
ZipEntry zipEntry = new ZipEntry(k + ".json");
|
||||
zipOutputStream.putNextEntry(zipEntry);
|
||||
hashMap.forEach((k, v) -> {
|
||||
try {
|
||||
ZipEntry zipEntry = new ZipEntry(k + ".json");
|
||||
zipOutputStream.putNextEntry(zipEntry);
|
||||
|
||||
zipOutputStream.write(JSON.toJSONString(v).getBytes(StandardCharsets.UTF_8));
|
||||
zipOutputStream.closeEntry();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
|
||||
try {
|
||||
zipOutputStream.close();
|
||||
zipOutputStream.write(JSON.toJSONString(v).getBytes(StandardCharsets.UTF_8));
|
||||
zipOutputStream.closeEntry();
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue