feat: 刷新字典缓存.
This commit is contained in:
@@ -0,0 +1,440 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator;
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.IdType;
|
||||
import com.baomidou.mybatisplus.generator.AutoGenerator;
|
||||
import com.baomidou.mybatisplus.generator.config.*;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
|
||||
import com.baomidou.mybatisplus.generator.config.querys.MySqlQuery;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.DateType;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
|
||||
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
|
||||
import com.orion.lang.constant.Const;
|
||||
import com.orion.lang.utils.ansi.AnsiAppender;
|
||||
import com.orion.lang.utils.ansi.style.AnsiFont;
|
||||
import com.orion.lang.utils.ansi.style.color.AnsiForeground;
|
||||
import com.orion.lang.utils.ext.yml.YmlExt;
|
||||
import com.orion.ops.framework.common.utils.Valid;
|
||||
import com.orion.ops.framework.mybatis.core.domain.BaseDO;
|
||||
import com.orion.ops.framework.mybatis.core.generator.engine.VelocityTemplateEngine;
|
||||
import com.orion.ops.framework.mybatis.core.generator.template.Table;
|
||||
import com.orion.ops.framework.mybatis.core.generator.template.Template;
|
||||
import com.orion.ops.framework.mybatis.core.mapper.IMapper;
|
||||
import org.apache.ibatis.annotations.Mapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Types;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 代码生成器
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2022/4/20 10:33
|
||||
*/
|
||||
public class CodeGenerator {
|
||||
|
||||
public static void main(String[] args) {
|
||||
// 输出路径
|
||||
String outputDir = "D:/MP/";
|
||||
// 作者
|
||||
String author = Const.ORION_AUTHOR;
|
||||
// 模块
|
||||
String module = "infra";
|
||||
// 生成的表
|
||||
Table[] tables = {
|
||||
// Template.create("preference", "用户偏好", "preference")
|
||||
// .enableProviderApi()
|
||||
// .cache("user:preference:{}:{}", "用户偏好 ${type} ${userId}")
|
||||
// .expire(1, TimeUnit.HOURS)
|
||||
// .vue("user", "preference")
|
||||
// .enums("type")
|
||||
// .names("APP", "HOST")
|
||||
// // 同 .value(1, 2)
|
||||
// .values("value", 1, 2)
|
||||
// // 同 .label("应用", "主机")
|
||||
// .values("label", "应用", "主机")
|
||||
// .color("blue", "green")
|
||||
// .build(),
|
||||
Template.create("history_value", "历史归档", "history")
|
||||
.enableProviderApi()
|
||||
.vue("meta", "history-value")
|
||||
.build(),
|
||||
Template.create("dict_key", "字典配置项", "dict")
|
||||
.cache("dict:keys", "字典配置项")
|
||||
.expire(1, TimeUnit.DAYS)
|
||||
.vue("system", "dict-key")
|
||||
.enums("value_type")
|
||||
.names("STRING", "INTEGER", "DECIMAL", "BOOLEAN", "COLOR")
|
||||
.label("字符串", "整数", "小数", "布尔值", "颜色")
|
||||
.build(),
|
||||
Template.create("dict_value", "字典配置值", "dict")
|
||||
.cache("dict:value:{}", "字典配置值 ${key}")
|
||||
.expire(1, TimeUnit.DAYS)
|
||||
.vue("system", "dict-value")
|
||||
.enableRowSelection()
|
||||
.build(),
|
||||
};
|
||||
// jdbc 配置 - 使用配置文件
|
||||
File yamlFile = new File("orion-ops-launch/src/main/resources/application-dev.yaml");
|
||||
YmlExt yaml = YmlExt.load(yamlFile);
|
||||
String url = yaml.getValue("spring.datasource.druid.url");
|
||||
String username = yaml.getValue("spring.datasource.druid.username");
|
||||
String password = yaml.getValue("spring.datasource.druid.password");
|
||||
|
||||
// 执行
|
||||
runGenerator(outputDir, author,
|
||||
url, username, password,
|
||||
tables, module);
|
||||
}
|
||||
|
||||
/**
|
||||
* 代码生成
|
||||
*/
|
||||
private static void runGenerator(String outputDir,
|
||||
String author,
|
||||
String url,
|
||||
String username,
|
||||
String password,
|
||||
Table[] tables,
|
||||
String module) {
|
||||
Valid.notEmpty(tables, "请先配置需要生成的表");
|
||||
|
||||
// 创建引擎
|
||||
VelocityTemplateEngine engine = getEngine(tables);
|
||||
|
||||
// 获取全局配置
|
||||
GlobalConfig globalConfig = getGlobalConfig(outputDir, author);
|
||||
|
||||
// 数据源配置
|
||||
DataSourceConfig dataSourceConfig = getDataSourceConfig(url, username, password);
|
||||
|
||||
// 策略配置
|
||||
StrategyConfig strategyConfig = getStrategyConfig(tables);
|
||||
|
||||
// 包名配置
|
||||
PackageConfig packageConfig = getPackageConfig(module);
|
||||
|
||||
// 模板配置
|
||||
TemplateConfig templateConfig = getTemplateConfig();
|
||||
|
||||
// 注入配置
|
||||
InjectionConfig injectionConfig = getInjectionConfig();
|
||||
|
||||
// 整合配置
|
||||
AutoGenerator ag = new AutoGenerator(dataSourceConfig)
|
||||
// 整合全局配置
|
||||
.global(globalConfig)
|
||||
// 整合表名配置
|
||||
.strategy(strategyConfig)
|
||||
// 整合包名配置
|
||||
.packageInfo(packageConfig)
|
||||
// 整合模板配置
|
||||
.template(templateConfig)
|
||||
// 整合注入配置
|
||||
.injection(injectionConfig);
|
||||
|
||||
// 执行
|
||||
ag.execute(engine);
|
||||
|
||||
// 打印提示信息
|
||||
printTips();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取渲染引擎
|
||||
*
|
||||
* @param tables 表
|
||||
* @return 渲染引擎
|
||||
*/
|
||||
private static VelocityTemplateEngine getEngine(Table[] tables) {
|
||||
return new VelocityTemplateEngine(tables);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取全局配置
|
||||
*
|
||||
* @param outputDir 输出地址
|
||||
* @param author 作者
|
||||
* @return config
|
||||
*/
|
||||
private static GlobalConfig getGlobalConfig(String outputDir, String author) {
|
||||
return new GlobalConfig.Builder()
|
||||
// 设置作者
|
||||
.author(author)
|
||||
// 生成路径
|
||||
.outputDir(outputDir)
|
||||
// 生成 spring doc 注解
|
||||
.enableSpringdoc()
|
||||
// date类型
|
||||
.dateType(DateType.ONLY_DATE)
|
||||
// 注释时间
|
||||
.commentDate("yyyy-M-d HH:mm")
|
||||
// 构建
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取数据源配置
|
||||
*
|
||||
* @param url url
|
||||
* @param username username
|
||||
* @param password password
|
||||
* @return 数据源配置
|
||||
*/
|
||||
private static DataSourceConfig getDataSourceConfig(String url, String username, String password) {
|
||||
return new DataSourceConfig.Builder(url, username, password)
|
||||
// 转换器
|
||||
.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {
|
||||
switch (metaInfo.getJdbcType().TYPE_CODE) {
|
||||
case Types.BIT:
|
||||
case Types.TINYINT:
|
||||
return DbColumnType.INTEGER;
|
||||
default:
|
||||
return typeRegistry.getColumnType(metaInfo);
|
||||
}
|
||||
})
|
||||
// 查询器
|
||||
.dbQuery(new MySqlQuery())
|
||||
// 构建
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取策略配置
|
||||
*
|
||||
* @param tables 生成的表名
|
||||
* @return 策略配置
|
||||
*/
|
||||
private static StrategyConfig getStrategyConfig(Table[] tables) {
|
||||
String[] tableNames = Arrays.stream(tables)
|
||||
.map(Table::getTableName)
|
||||
.toArray(String[]::new);
|
||||
// 策略配置
|
||||
return new StrategyConfig.Builder()
|
||||
// 生成的表
|
||||
.addInclude(tableNames)
|
||||
// 全局大写命名
|
||||
.enableCapitalMode()
|
||||
// 实体配置
|
||||
.entityBuilder()
|
||||
// 下滑线转驼峰命名策略
|
||||
.naming(NamingStrategy.underline_to_camel)
|
||||
// 实体父类
|
||||
.superClass(BaseDO.class)
|
||||
// 实体父类字段
|
||||
.addSuperEntityColumns("create_time", "update_time", "creator", "updater", "deleted")
|
||||
// 启用lombok
|
||||
.enableLombok()
|
||||
// 主键策略
|
||||
.idType(IdType.AUTO)
|
||||
// 添加字段注解
|
||||
.enableTableFieldAnnotation()
|
||||
// 实体文件名称
|
||||
.formatFileName("%sDO")
|
||||
// 覆盖实体文件
|
||||
.enableFileOverride()
|
||||
// mapper 配置
|
||||
.mapperBuilder()
|
||||
// dao 添加 @Mapper
|
||||
.mapperAnnotation(Mapper.class)
|
||||
// mapper 父类
|
||||
.superClass(IMapper.class)
|
||||
// 生成 BaseResultMap
|
||||
.enableBaseResultMap()
|
||||
// 生成 BaseColumnList
|
||||
.enableBaseColumnList()
|
||||
// mapper 文件名称
|
||||
.formatMapperFileName("%sDAO")
|
||||
// xml 文件名称
|
||||
.formatXmlFileName("%sMapper")
|
||||
// 覆盖 mapper 文件
|
||||
.enableFileOverride()
|
||||
// controller 配置
|
||||
.controllerBuilder()
|
||||
// controller 文件名称
|
||||
.formatFileName("%sController")
|
||||
// 脊柱命名法
|
||||
.enableHyphenStyle()
|
||||
// @RestController
|
||||
.enableRestStyle()
|
||||
// 覆盖 controller 文件
|
||||
.enableFileOverride()
|
||||
// service 配置
|
||||
.serviceBuilder()
|
||||
// 覆盖 service 文件
|
||||
.enableFileOverride()
|
||||
// service 名称
|
||||
.formatServiceFileName("%sService")
|
||||
// service impl 名称
|
||||
.formatServiceImplFileName("%sServiceImpl")
|
||||
// 构建
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取包名配置
|
||||
*
|
||||
* @param module 模块
|
||||
* @return 包名配置
|
||||
*/
|
||||
private static PackageConfig getPackageConfig(String module) {
|
||||
return new PackageConfig.Builder()
|
||||
// 声明父包
|
||||
.parent("com.orion.ops.module")
|
||||
// 模块名称
|
||||
.moduleName(module)
|
||||
// 实体类的包
|
||||
.entity("entity.domain")
|
||||
// 映射接口的包
|
||||
.mapper("dao")
|
||||
// 映射文件的包
|
||||
.xml("mapper")
|
||||
// service接口的包
|
||||
.service("service")
|
||||
// serviceImpl接口的包
|
||||
.serviceImpl("service.impl")
|
||||
// controller接口的包
|
||||
.controller("controller")
|
||||
// 构建
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取模板配置
|
||||
*
|
||||
* @return 模板配置
|
||||
*/
|
||||
private static TemplateConfig getTemplateConfig() {
|
||||
return new TemplateConfig.Builder()
|
||||
.controller("/templates/orion-server-module-controller.java.vm")
|
||||
.entity("/templates/orion-server-module-entity-do.java.vm")
|
||||
.service("/templates/orion-server-module-service.java.vm")
|
||||
.serviceImpl("/templates/orion-server-module-service-impl.java.vm")
|
||||
.mapper("/templates/orion-server-module-mapper.java.vm")
|
||||
.xml("/templates/orion-server-module-mapper.xml.vm")
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取注入配置
|
||||
*
|
||||
* @return 注入配置
|
||||
*/
|
||||
private static InjectionConfig getInjectionConfig() {
|
||||
String[][] customFileDefineArr = new String[][]{
|
||||
// -------------------- 后端 - module --------------------
|
||||
// http 文件
|
||||
new String[]{"/templates/orion-server-module-controller.http.vm", "${type}Controller.http", "controller"},
|
||||
// vo 文件
|
||||
new String[]{"/templates/orion-server-module-entity-vo.java.vm", "${type}VO.java", "entity.vo"},
|
||||
// create request 文件
|
||||
new String[]{"/templates/orion-server-module-entity-request-create.java.vm", "${type}CreateRequest.java", "entity.request.${bizPackage}"},
|
||||
// update request 文件
|
||||
new String[]{"/templates/orion-server-module-entity-request-update.java.vm", "${type}UpdateRequest.java", "entity.request.${bizPackage}"},
|
||||
// query request 文件
|
||||
new String[]{"/templates/orion-server-module-entity-request-query.java.vm", "${type}QueryRequest.java", "entity.request.${bizPackage}"},
|
||||
// export 文件
|
||||
new String[]{"/templates/orion-server-module-entity-export.java.vm", "${type}Export.java", "entity.export"},
|
||||
// convert 文件
|
||||
new String[]{"/templates/orion-server-module-convert.java.vm", "${type}Convert.java", "convert"},
|
||||
// cache dto 文件
|
||||
new String[]{"/templates/orion-server-module-cache-dto.java.vm", "${type}CacheDTO.java", "entity.dto"},
|
||||
// cache key define 文件
|
||||
new String[]{"/templates/orion-server-module-cache-key-define.java.vm", "${type}CacheKeyDefine.java", "define.cache"},
|
||||
// operator log define 文件
|
||||
new String[]{"/templates/orion-server-module-operator-key-define.java.vm", "${type}OperatorType.java", "define.operator"},
|
||||
// -------------------- 后端 - provider --------------------
|
||||
// api 文件
|
||||
new String[]{"/templates/orion-server-provider-api.java.vm", "${type}Api.java", "api"},
|
||||
// api impl 文件
|
||||
new String[]{"/templates/orion-server-provider-api-impl.java.vm", "${type}ApiImpl.java", "api.impl"},
|
||||
// dto 文件
|
||||
new String[]{"/templates/orion-server-provider-entity-dto.java.vm", "${type}DTO.java", "entity.dto.${bizPackage}"},
|
||||
// create dto 文件
|
||||
new String[]{"/templates/orion-server-provider-entity-dto-create.java.vm", "${type}CreateDTO.java", "entity.dto.${bizPackage}"},
|
||||
// update dto 文件
|
||||
new String[]{"/templates/orion-server-provider-entity-dto-update.java.vm", "${type}UpdateDTO.java", "entity.dto.${bizPackage}"},
|
||||
// query dto 文件
|
||||
new String[]{"/templates/orion-server-provider-entity-dto-query.java.vm", "${type}QueryDTO.java", "entity.dto.${bizPackage}"},
|
||||
// convert 文件
|
||||
new String[]{"/templates/orion-server-provider-convert.java.vm", "${type}ProviderConvert.java", "convert"},
|
||||
// -------------------- 后端 - test --------------------
|
||||
// service unit test 文件
|
||||
new String[]{"/templates/orion-server-test-service-impl-tests.java.vm", "${type}ServiceImplTests.java", "service.impl"},
|
||||
// api unit test 文件
|
||||
new String[]{"/templates/orion-server-test-api-impl-tests.java.vm", "${type}ApiImplTests.java", "api.impl"},
|
||||
// create table sql 文件
|
||||
new String[]{"/templates/orion-server-test-create-table.sql.vm", "create-table-h2-${tableName}.sql", "sql"},
|
||||
// -------------------- 前端 --------------------
|
||||
// api 文件
|
||||
new String[]{"/templates/orion-vue-api.ts.vm", "${feature}.ts", "vue/api/${module}"},
|
||||
// router 文件
|
||||
new String[]{"/templates/orion-vue-router.ts.vm", "${module}.${feature}.ts", "vue/router/routes/modules"},
|
||||
// views index.ts 文件
|
||||
new String[]{"/templates/orion-vue-views-index.vue.vm", "index.vue", "vue/views/${module}/${feature}"},
|
||||
// form-modal.vue 文件
|
||||
new String[]{"/templates/orion-vue-views-components-form-modal.vue.vm", "${feature}-form-modal.vue", "vue/views/${module}/${feature}/components"},
|
||||
// form-drawer.vue 文件
|
||||
new String[]{"/templates/orion-vue-views-components-form-drawer.vue.vm", "${feature}-form-drawer.vue", "vue/views/${module}/${feature}/components"},
|
||||
// table.vue 文件
|
||||
new String[]{"/templates/orion-vue-views-components-table.vue.vm", "${feature}-table.vue", "vue/views/${module}/${feature}/components"},
|
||||
// card-list.vue 文件
|
||||
new String[]{"/templates/orion-vue-views-components-card-list.vue.vm", "${feature}-card-list.vue", "vue/views/${module}/${feature}/components"},
|
||||
// enum.types.ts 文件
|
||||
new String[]{"/templates/orion-vue-views-types-enum.types.ts.vm", "enum.types.ts", "vue/views/${module}/${feature}/types"},
|
||||
// const.ts 文件
|
||||
new String[]{"/templates/orion-vue-views-types-const.ts.vm", "const.ts", "vue/views/${module}/${feature}/types"},
|
||||
// form.rules.ts 文件
|
||||
new String[]{"/templates/orion-vue-views-types-form.rules.ts.vm", "form.rules.ts", "vue/views/${module}/${feature}/types"},
|
||||
// table.columns.ts 文件
|
||||
new String[]{"/templates/orion-vue-views-types-table.columns.ts.vm", "table.columns.ts", "vue/views/${module}/${feature}/types"},
|
||||
// card.fields.ts 文件
|
||||
new String[]{"/templates/orion-vue-views-types-card.fields.ts.vm", "card.fields.ts", "vue/views/${module}/${feature}/types"},
|
||||
// menu.sql 文件
|
||||
new String[]{"/templates/orion-sql-menu.sql.vm", "${feature}-menu.sql", "sql"},
|
||||
};
|
||||
|
||||
// 构建文件
|
||||
List<CustomFile> customerFiles = Arrays.stream(customFileDefineArr)
|
||||
.map(s -> new CustomFile.Builder()
|
||||
// 覆盖文件
|
||||
.enableFileOverride()
|
||||
// 模板路径
|
||||
.templatePath(s[0])
|
||||
// 文件名
|
||||
.fileName(s[1])
|
||||
// 包名
|
||||
.packageName(s[2])
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 注入配置
|
||||
return new InjectionConfig.Builder()
|
||||
// 自定义 文件
|
||||
.customFile(customerFiles)
|
||||
// 构建
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
* 打印提示信息
|
||||
*/
|
||||
private static void printTips() {
|
||||
String line = AnsiAppender.create()
|
||||
.append(AnsiForeground.BRIGHT_GREEN.and(AnsiFont.BOLD), "\n:: 代码生成完毕 ^_^ ::\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 后端代码复制后请先 clean 父工程\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 后端代码需要自行修改缓存逻辑\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 后端代码修改完成后请先执行单元测试检测是否正常\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- vue 代码需要注意同一模块的 router 需要自行合并\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- vue 枚举需要自行更改数据类型\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 菜单 sql 执行完成后 需要在系统菜单页面刷新缓存\n")
|
||||
.append(AnsiForeground.BRIGHT_BLUE.and(AnsiFont.BOLD), "- 字典 sql 执行完成后 需要在字典配置项页面刷新缓存\n")
|
||||
.toString();
|
||||
System.out.print(line);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.engine;
|
||||
|
||||
import com.orion.lang.define.collect.MultiLinkedHashMap;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
/**
|
||||
* vue 枚举
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 16:50
|
||||
*/
|
||||
@Data
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class EnumMeta {
|
||||
|
||||
/**
|
||||
* 类名称
|
||||
*/
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 备注
|
||||
*/
|
||||
private String comment;
|
||||
|
||||
/**
|
||||
* 配置
|
||||
*/
|
||||
private MultiLinkedHashMap<String, String, Object> info;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,499 @@
|
||||
/*
|
||||
* Copyright (c) 2011-2022, baomidou (jobob@qq.com).
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package com.orion.ops.framework.mybatis.core.generator.engine;
|
||||
|
||||
import com.baomidou.mybatisplus.core.toolkit.StringPool;
|
||||
import com.baomidou.mybatisplus.generator.config.ConstVal;
|
||||
import com.baomidou.mybatisplus.generator.config.OutputFile;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder;
|
||||
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableField;
|
||||
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
|
||||
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
|
||||
import com.orion.lang.define.collect.MultiLinkedHashMap;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.VariableStyles;
|
||||
import com.orion.lang.utils.io.Files1;
|
||||
import com.orion.lang.utils.reflect.BeanMap;
|
||||
import com.orion.lang.utils.reflect.Fields;
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
import com.orion.ops.framework.common.constant.OrionOpsProConst;
|
||||
import com.orion.ops.framework.mybatis.core.generator.template.Table;
|
||||
import com.orion.ops.framework.mybatis.core.generator.template.VueEnum;
|
||||
import org.apache.velocity.Template;
|
||||
import org.apache.velocity.VelocityContext;
|
||||
import org.apache.velocity.app.Velocity;
|
||||
import org.apache.velocity.app.VelocityEngine;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.util.*;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 代码生成器 Velocity 引擎
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2022/4/20 10:33
|
||||
*/
|
||||
public class VelocityTemplateEngine extends AbstractTemplateEngine {
|
||||
|
||||
private final Map<String, Table> tables;
|
||||
|
||||
private VelocityEngine velocityEngine;
|
||||
|
||||
public VelocityTemplateEngine(Table[] tables) {
|
||||
this.tables = Arrays.stream(tables)
|
||||
.collect(Collectors.toMap(Table::getTableName, Function.identity()));
|
||||
}
|
||||
|
||||
{
|
||||
try {
|
||||
Class.forName("org.apache.velocity.util.DuckType");
|
||||
} catch (ClassNotFoundException e) {
|
||||
LOGGER.warn("Velocity 1.x is outdated, please upgrade to 2.x or later.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public VelocityTemplateEngine init(@NotNull ConfigBuilder configBuilder) {
|
||||
if (velocityEngine == null) {
|
||||
Properties p = new Properties();
|
||||
p.setProperty(ConstVal.VM_LOAD_PATH_KEY, ConstVal.VM_LOAD_PATH_VALUE);
|
||||
p.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, StringPool.EMPTY);
|
||||
p.setProperty(Velocity.ENCODING_DEFAULT, ConstVal.UTF8);
|
||||
p.setProperty(Velocity.INPUT_ENCODING, ConstVal.UTF8);
|
||||
p.setProperty("file.resource.loader.unicode", StringPool.TRUE);
|
||||
this.velocityEngine = new VelocityEngine(p);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void writer(@NotNull Map<String, Object> objectMap, @NotNull String templatePath, @NotNull File outputFile) throws Exception {
|
||||
Template template = velocityEngine.getTemplate(templatePath, ConstVal.UTF8);
|
||||
try (FileOutputStream fos = new FileOutputStream(outputFile);
|
||||
OutputStreamWriter ow = new OutputStreamWriter(fos, ConstVal.UTF8);
|
||||
BufferedWriter writer = new BufferedWriter(ow)) {
|
||||
template.merge(new VelocityContext(objectMap), writer);
|
||||
}
|
||||
LOGGER.debug("模板: " + templatePath + "; 文件: " + outputFile);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public String templateFilePath(@NotNull String filePath) {
|
||||
final String dotVm = ".vm";
|
||||
return filePath.endsWith(dotVm) ? filePath : filePath + dotVm;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void outputCustomFile(@NotNull List<CustomFile> customFiles, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
|
||||
// 创建自定义文件副本文件
|
||||
customFiles = this.createCustomFilesBackup(customFiles, tableInfo);
|
||||
// 添加表元数据
|
||||
this.addTableMeta(tableInfo, objectMap);
|
||||
// 替换自定义包名
|
||||
this.replacePackageName(customFiles, tableInfo, objectMap);
|
||||
// 添加注释元数据
|
||||
this.addApiCommentMeta(tableInfo, objectMap);
|
||||
// 生成后端文件
|
||||
this.generatorServerFile(customFiles, tableInfo, objectMap);
|
||||
// 生成前端文件
|
||||
this.generatorVueFile(customFiles, tableInfo, objectMap);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建自定义文件副本对象
|
||||
* <p>
|
||||
* - 根据类型进行移除不需要生成的模板
|
||||
*
|
||||
* @param originCustomerFile originCustomerFile
|
||||
* @param tableInfo tableInfo
|
||||
* @return backup
|
||||
*/
|
||||
private List<CustomFile> createCustomFilesBackup(@NotNull List<CustomFile> originCustomerFile,
|
||||
@NotNull TableInfo tableInfo) {
|
||||
// 生成文件副本
|
||||
List<CustomFile> files = originCustomerFile.stream().map(s ->
|
||||
new CustomFile.Builder()
|
||||
.enableFileOverride()
|
||||
.templatePath(s.getTemplatePath())
|
||||
.filePath(s.getFilePath())
|
||||
.fileName(s.getFileName())
|
||||
.packageName(s.getPackageName())
|
||||
.build())
|
||||
.collect(Collectors.toList());
|
||||
// 获取 table
|
||||
Table table = tables.get(tableInfo.getName());
|
||||
// 不生成对外 api 文件
|
||||
if (!table.isEnableProviderApi()) {
|
||||
files.removeIf(file -> this.isServerProviderFile(file.getTemplatePath()));
|
||||
// 不生成对外 api 单元测试文件
|
||||
if (table.isEnableUnitTest()) {
|
||||
files.removeIf(file -> this.isServerProviderTestFile(file.getTemplatePath()));
|
||||
}
|
||||
}
|
||||
// 不生成单元测试文件
|
||||
if (!table.isEnableUnitTest()) {
|
||||
files.removeIf(file -> this.isServerUnitTestFile(file.getTemplatePath()));
|
||||
}
|
||||
// 不生成缓存文件
|
||||
if (!table.isEnableCache()) {
|
||||
files.removeIf(file -> this.isServerCacheFile(file.getTemplatePath()));
|
||||
}
|
||||
// 不生成 vue 文件
|
||||
if (!table.isEnableVue()) {
|
||||
files.removeIf(file -> this.isVueFile(file.getTemplatePath()));
|
||||
}
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入表元数据
|
||||
*
|
||||
* @param tableInfo tableInfo
|
||||
* @param objectMap objectMap
|
||||
*/
|
||||
private void addTableMeta(@NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
|
||||
// http 注释标识
|
||||
objectMap.put("httpComment", "###");
|
||||
// 版本
|
||||
objectMap.put("since", OrionOpsProConst.VERSION);
|
||||
// 替换业务注释
|
||||
tableInfo.setComment(tables.get(tableInfo.getName()).getComment());
|
||||
Table table = tables.get(tableInfo.getName());
|
||||
// 缓存元数据
|
||||
Map<String, Object> cacheMeta = this.pickTableMeta(table,
|
||||
"enableCache", "cacheKey", "cacheDesc",
|
||||
"cacheExpired", "cacheExpireTime", "cacheExpireUnit");
|
||||
objectMap.put("cacheMeta", cacheMeta);
|
||||
// 实体名称
|
||||
String domainName = tableInfo.getEntityName();
|
||||
String mappingHyphen = objectMap.get("controllerMappingHyphen").toString();
|
||||
String entityName = domainName.substring(0, domainName.length() - 2);
|
||||
// 类型
|
||||
objectMap.put("type", entityName);
|
||||
// 类型首字母小写
|
||||
objectMap.put("typeLower", Strings.firstLower(entityName));
|
||||
// 类型脊柱名称
|
||||
objectMap.put("typeHyphen", mappingHyphen.substring(0, mappingHyphen.length() - 3));
|
||||
// 类型常量
|
||||
objectMap.put("typeConst", VariableStyles.BIG_HUMP.toSerpentine(entityName).toUpperCase());
|
||||
}
|
||||
|
||||
/**
|
||||
* 替换自定义文件包
|
||||
*
|
||||
* @param customFiles 自定义文件
|
||||
* @param tableInfo tableInfo
|
||||
* @param objectMap objectMap
|
||||
*/
|
||||
private void replacePackageName(@NotNull List<CustomFile> customFiles, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
|
||||
// 替换包名
|
||||
customFiles.forEach(s -> {
|
||||
// 反射调用 setter 方法
|
||||
BiConsumer<String, Object> callSetter = (field, value) -> Fields.setFieldValue(s, field, value);
|
||||
String packageName = s.getPackageName();
|
||||
// 替换文件业务包名
|
||||
if (packageName.contains(Const.DOLLAR)) {
|
||||
Map<String, Object> meta = new HashMap<>(4);
|
||||
meta.put("bizPackage", tables.get(tableInfo.getName()).getBizPackage());
|
||||
// 调用 setter
|
||||
callSetter.accept("packageName", Strings.format(packageName, meta));
|
||||
}
|
||||
});
|
||||
|
||||
// 包转换器
|
||||
Function<Predicate<String>, List<String>> packageConverter = conv ->
|
||||
customFiles.stream()
|
||||
.filter(s -> conv.test(s.getTemplatePath()))
|
||||
.map(CustomFile::getPackageName)
|
||||
.map(s -> getConfigBuilder().getPackageConfig().getParent() + "." + s)
|
||||
.distinct()
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 自定义 module 文件的包 (导入用)
|
||||
List<String> customModuleFilePackages = packageConverter.apply(s -> s.contains(".java.vm") && s.contains("orion-server-module"));
|
||||
objectMap.put("customModuleFilePackages", customModuleFilePackages);
|
||||
|
||||
// 自定义 provider entity 文件的包 (导入用)
|
||||
List<String> customProviderEntityFilePackages = packageConverter.apply(s -> s.contains(".java.vm") && s.contains("orion-server-provider-entity"));
|
||||
objectMap.put("customProviderEntityFilePackages", customProviderEntityFilePackages);
|
||||
|
||||
// 自定义 provider interface 文件的包 (导入用)
|
||||
List<String> customProviderFilePackages = packageConverter.apply(s -> s.contains(".java.vm") && s.contains("orion-server-provider"));
|
||||
objectMap.put("customProviderFilePackages", customProviderFilePackages);
|
||||
}
|
||||
|
||||
/**
|
||||
* 插入 api 注释
|
||||
*
|
||||
* @param tableInfo tableInfo
|
||||
* @param objectMap objectMap
|
||||
*/
|
||||
private void addApiCommentMeta(@NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
|
||||
Map<String, String> map = new HashMap<>(12);
|
||||
objectMap.put("apiComment", map);
|
||||
String comment = tableInfo.getComment();
|
||||
map.put("create", "创建" + comment);
|
||||
map.put("updateAll", "根据条件更新" + comment);
|
||||
map.put("updateById", "更新" + comment);
|
||||
map.put("getById", "查询" + comment);
|
||||
map.put("getByIdList", "批量查询" + comment);
|
||||
map.put("queryList", "查询全部" + comment);
|
||||
map.put("queryListByCache", "通过缓存查询" + comment);
|
||||
map.put("queryPage", "分页查询" + comment);
|
||||
map.put("queryCount", "查询" + comment + "数量");
|
||||
map.put("deleteById", "删除" + comment);
|
||||
map.put("deleteAll", "根据条件删除" + comment);
|
||||
map.put("batchDelete", "批量删除" + comment);
|
||||
map.put("export", "导出" + comment);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成后端文件
|
||||
*
|
||||
* @param customFiles customFiles
|
||||
* @param tableInfo tableInfo
|
||||
* @param objectMap objectMap
|
||||
*/
|
||||
private void generatorServerFile(@NotNull List<CustomFile> customFiles, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
|
||||
// 过滤文件
|
||||
customFiles = customFiles.stream()
|
||||
.filter(s -> this.isServerFile(s.getTemplatePath()))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// 生成文件
|
||||
customFiles.forEach(file -> {
|
||||
// 获取 parent package
|
||||
String currentPackage = getConfigBuilder().getPackageConfig().getParent() + "." + file.getPackageName();
|
||||
// 设置当前包
|
||||
objectMap.put("currentPackage", currentPackage);
|
||||
|
||||
// 文件路径
|
||||
String filePath = this.getPathInfo(OutputFile.parent) + File.separator + file.getPackageName()
|
||||
.replaceAll("\\.", StringPool.BACK_SLASH + File.separator);
|
||||
// 文件名称
|
||||
Map<String, Object> fileNameMeta = new HashMap<>(4);
|
||||
fileNameMeta.put("type", objectMap.get("type"));
|
||||
fileNameMeta.put("tableName", tableInfo.getName());
|
||||
String fileName = filePath + File.separator + Strings.format(file.getFileName(), fileNameMeta);
|
||||
// 渲染文件
|
||||
this.outputFile(Files1.newFile(fileName), objectMap, file.getTemplatePath(), file.isFileOverride());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成前端文件
|
||||
*
|
||||
* @param customFiles customFiles
|
||||
* @param tableInfo tableInfo
|
||||
* @param objectMap objectMap
|
||||
*/
|
||||
private void generatorVueFile(@NotNull List<CustomFile> customFiles, @NotNull TableInfo tableInfo, @NotNull Map<String, Object> objectMap) {
|
||||
// 不生成 vue 文件
|
||||
if (!tables.get(tableInfo.getName()).isEnableVue()) {
|
||||
return;
|
||||
}
|
||||
// 过滤文件
|
||||
customFiles = customFiles.stream()
|
||||
.filter(s -> this.isVueFile(s.getTemplatePath()))
|
||||
.collect(Collectors.toList());
|
||||
// 设置前端元数据
|
||||
Table table = tables.get(tableInfo.getName());
|
||||
Map<String, Object> vueMeta = this.pickTableMeta(table, "module", "feature", "enableDrawerForm", "enableRowSelection", "enableCardView");
|
||||
// 模块名称实体
|
||||
vueMeta.put("moduleEntity", VariableStyles.SPINE.toBigHump(table.getModule()));
|
||||
// 模块名称实体
|
||||
vueMeta.put("moduleEntityFirstLower", Strings.firstLower(vueMeta.get("moduleEntity")));
|
||||
// 模块名称常量
|
||||
vueMeta.put("moduleConst", VariableStyles.SPINE.toSerpentine(table.getModule()).toUpperCase());
|
||||
// 功能名称实体
|
||||
vueMeta.put("featureEntity", VariableStyles.SPINE.toBigHump(table.getFeature()));
|
||||
// 功能名称实体
|
||||
vueMeta.put("featureEntityFirstLower", Strings.firstLower(vueMeta.get("featureEntity")));
|
||||
// 功能名称常量
|
||||
vueMeta.put("featureConst", VariableStyles.SPINE.toSerpentine(table.getFeature()).toUpperCase());
|
||||
// 枚举
|
||||
vueMeta.put("enums", this.getEnumMap(tableInfo, table));
|
||||
objectMap.put("vue", vueMeta);
|
||||
|
||||
// 生成文件
|
||||
customFiles.forEach(file -> {
|
||||
// 文件路径
|
||||
String filePath = getConfigBuilder().getGlobalConfig().getOutputDir()
|
||||
+ "/" + Strings.format(file.getPackageName(), vueMeta)
|
||||
+ "/" + Strings.format(file.getFileName(), vueMeta);
|
||||
// 渲染文件
|
||||
this.outputFile(Files1.newFile(filePath), objectMap, file.getTemplatePath(), file.isFileOverride());
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为后端文件
|
||||
*
|
||||
* @param templatePath templatePath
|
||||
* @return 是否为后端文件
|
||||
*/
|
||||
private boolean isServerFile(String templatePath) {
|
||||
return templatePath.contains("orion-server");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为后端 provider 文件
|
||||
*
|
||||
* @param templatePath templatePath
|
||||
* @return 是否为后端 provider 文件
|
||||
*/
|
||||
private boolean isServerProviderFile(String templatePath) {
|
||||
return templatePath.contains("orion-server-provider");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为后端 provider 单元测试文件
|
||||
*
|
||||
* @param templatePath templatePath
|
||||
* @return 是否为后端 provider 单元测试文件
|
||||
*/
|
||||
private boolean isServerProviderTestFile(String templatePath) {
|
||||
return templatePath.contains("orion-server-test-api");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为后端单元测试文件
|
||||
*
|
||||
* @param templatePath templatePath
|
||||
* @return 是否为后端单元测试文件
|
||||
*/
|
||||
private boolean isServerUnitTestFile(String templatePath) {
|
||||
return templatePath.contains("orion-server-test");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为后端缓存文件
|
||||
*
|
||||
* @param templatePath templatePath
|
||||
* @return 是否为后端缓存文件
|
||||
*/
|
||||
private boolean isServerCacheFile(String templatePath) {
|
||||
return templatePath.contains("orion-server-module-cache");
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否为 vue 文件
|
||||
*
|
||||
* @param templatePath templatePath
|
||||
* @return 是否为 vue 文件
|
||||
*/
|
||||
private boolean isVueFile(String templatePath) {
|
||||
return templatePath.contains("orion-vue-") ||
|
||||
templatePath.contains("orion-sql-menu.sql");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取表元数据
|
||||
*
|
||||
* @param table table
|
||||
* @param keys keys
|
||||
* @return meta
|
||||
*/
|
||||
private Map<String, Object> pickTableMeta(Table table, String... keys) {
|
||||
BeanMap beanMap = BeanMap.create(table);
|
||||
Map<String, Object> tableMeta = new HashMap<>();
|
||||
for (String key : keys) {
|
||||
tableMeta.put(key, beanMap.get(key));
|
||||
}
|
||||
return tableMeta;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取枚举
|
||||
*
|
||||
* @param tableInfo tableInfo
|
||||
* @param table table
|
||||
* @return enumMap
|
||||
*/
|
||||
private Map<String, EnumMeta> getEnumMap(TableInfo tableInfo, Table table) {
|
||||
// 枚举值
|
||||
Map<String, EnumMeta> enumMap = new LinkedHashMap<>();
|
||||
for (VueEnum meta : table.getEnums()) {
|
||||
// 检查字段是否存在
|
||||
String variable = meta.getVariable();
|
||||
TableField tableField = tableInfo.getFields()
|
||||
.stream()
|
||||
.filter(s -> variable.equals(s.getName()) || variable.equals(s.getPropertyName()))
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new RuntimeException("未查询到枚举映射字段 " + variable));
|
||||
// 设置枚举名称
|
||||
if (meta.getClassName() == null) {
|
||||
meta.setClassName(Strings.firstUpper(tableField.getPropertyName()) + "Enum");
|
||||
}
|
||||
// 设置枚举注释
|
||||
if (meta.getComment() == null) {
|
||||
meta.setComment(Strings.def(tableField.getComment(), meta.getClassName()));
|
||||
}
|
||||
// 设置枚举
|
||||
MultiLinkedHashMap<String, String, Object> enumInfo = new MultiLinkedHashMap<>();
|
||||
for (int i = 0; i < meta.getNames().size(); i++) {
|
||||
// 枚举名称
|
||||
String name = meta.getNames().get(i);
|
||||
// 设置枚举值
|
||||
for (int j = 0; j < meta.getFields().size(); j++) {
|
||||
String field = meta.getFields().get(j);
|
||||
Object value = safeGet(safeGet(meta.getValues(), j), i);
|
||||
enumInfo.put(name, field, value);
|
||||
}
|
||||
// 检查是否有 value
|
||||
if (!meta.getFields().contains(Const.VALUE)) {
|
||||
// 没有 value 用 name
|
||||
enumInfo.put(name, Const.VALUE, name);
|
||||
}
|
||||
}
|
||||
enumMap.put(tableField.getPropertyName(), new EnumMeta(meta.getClassName(), meta.getComment(), enumInfo));
|
||||
}
|
||||
return enumMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取值
|
||||
*
|
||||
* @param list list
|
||||
* @param index index
|
||||
* @param <T> T
|
||||
* @return value
|
||||
*/
|
||||
private <T> T safeGet(List<T> list, int index) {
|
||||
if (list == null) {
|
||||
return null;
|
||||
}
|
||||
if (list.size() > index) {
|
||||
return list.get(index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* 后端代码缓存模板
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 1:14
|
||||
*/
|
||||
public class CacheTemplate extends ServerTemplate {
|
||||
|
||||
public CacheTemplate(Table table) {
|
||||
this(table, table.cacheKey, table.cacheDesc);
|
||||
}
|
||||
|
||||
public CacheTemplate(Table table, String key) {
|
||||
this(table, key, table.cacheDesc);
|
||||
}
|
||||
|
||||
public CacheTemplate(Table table, String key, String desc) {
|
||||
super(table);
|
||||
table.enableCache = true;
|
||||
table.cacheExpireTime = 1;
|
||||
table.cacheExpireUnit = TimeUnit.HOURS;
|
||||
table.cacheKey = key;
|
||||
table.cacheDesc = desc;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存 key
|
||||
*
|
||||
* @param key key
|
||||
* @return this
|
||||
*/
|
||||
public CacheTemplate key(String key) {
|
||||
table.cacheKey = key;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存 key
|
||||
*
|
||||
* @param key key
|
||||
* @return this
|
||||
*/
|
||||
public CacheTemplate key(String key, String desc) {
|
||||
table.cacheKey = key;
|
||||
table.cacheDesc = desc;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存描述
|
||||
*
|
||||
* @param desc desc
|
||||
* @return this
|
||||
*/
|
||||
public CacheTemplate desc(String desc) {
|
||||
table.cacheDesc = desc;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存过期时间
|
||||
*
|
||||
* @param time time
|
||||
* @return this
|
||||
*/
|
||||
public CacheTemplate expireTime(Integer time) {
|
||||
table.cacheExpired = true;
|
||||
table.cacheExpireTime = time;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存过期时间单位
|
||||
*
|
||||
* @param unit unit
|
||||
* @return this
|
||||
*/
|
||||
public CacheTemplate expireUnit(TimeUnit unit) {
|
||||
table.cacheExpired = true;
|
||||
table.cacheExpireUnit = unit;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置缓存过期时间
|
||||
*
|
||||
* @param time time
|
||||
* @param unit unit
|
||||
* @return this
|
||||
*/
|
||||
public CacheTemplate expire(Integer time, TimeUnit unit) {
|
||||
table.cacheExpired = true;
|
||||
table.cacheExpireTime = time;
|
||||
table.cacheExpireUnit = unit;
|
||||
return this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
import com.orion.lang.utils.Enums;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.lang.utils.reflect.Fields;
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* 前端代码枚举模板
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 1:14
|
||||
*/
|
||||
public class EnumsTemplate extends VueTemplate {
|
||||
|
||||
private final VueEnum vueEnum;
|
||||
|
||||
public EnumsTemplate(Table table, String variable) {
|
||||
this(table, variable, (String) null);
|
||||
}
|
||||
|
||||
public EnumsTemplate(Table table, String variable, String className) {
|
||||
super(table);
|
||||
this.vueEnum = new VueEnum(variable, className);
|
||||
table.enums.add(vueEnum);
|
||||
}
|
||||
|
||||
public EnumsTemplate(Table table, String variable, Class<? extends Enum<?>> enumClass) {
|
||||
super(table);
|
||||
this.vueEnum = new VueEnum(variable);
|
||||
table.enums.add(vueEnum);
|
||||
this.parseEnumMeta(enumClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* 解析枚举
|
||||
*
|
||||
* @param enumClass enumClass
|
||||
*/
|
||||
private void parseEnumMeta(Class<? extends Enum<?>> enumClass) {
|
||||
// 获取枚举
|
||||
List<? extends Enum<?>> enumList = Lists.of(enumClass.getEnumConstants());
|
||||
// 枚举名称
|
||||
List<String> names = enumList.stream()
|
||||
.map(Enum::name)
|
||||
.collect(Collectors.toList());
|
||||
// 枚举字段
|
||||
List<String> fields = Enums.getFields(enumClass);
|
||||
// 枚举值
|
||||
List<List<Object>> values = fields.stream()
|
||||
.map(field -> enumList.stream()
|
||||
.map(enumItem -> Fields.getFieldValue(enumItem, field))
|
||||
.collect(Collectors.toList()))
|
||||
.collect(Collectors.toList());
|
||||
vueEnum.className = enumClass.getSimpleName();
|
||||
vueEnum.names.addAll(names);
|
||||
vueEnum.fields.addAll(fields);
|
||||
vueEnum.values.addAll(values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置类名
|
||||
*
|
||||
* @param className className
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate className(String className) {
|
||||
vueEnum.className = className;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置注释
|
||||
*
|
||||
* @param comment comment
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate comment(String comment) {
|
||||
vueEnum.comment = comment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置枚举名称
|
||||
*
|
||||
* @param names names
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate names(String... names) {
|
||||
vueEnum.names.addAll(Lists.of(names));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置字段值
|
||||
*
|
||||
* @param values values
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate values(String field, Object... values) {
|
||||
vueEnum.fields.add(field);
|
||||
vueEnum.values.add(Lists.of(values));
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 label
|
||||
*
|
||||
* @param labels labels
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate label(Object... labels) {
|
||||
return this.values(Const.LABEL, labels);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 value
|
||||
* 如果 value 和 name 相同可以省略 (无 value 自动使用 name)
|
||||
*
|
||||
* @param values values
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate value(Object... values) {
|
||||
return this.values(Const.VALUE, values);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 color
|
||||
*
|
||||
* @param colors colors
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate color(Object... colors) {
|
||||
return this.values(Const.COLOR, colors);
|
||||
}
|
||||
|
||||
/**
|
||||
* 添加 status
|
||||
*
|
||||
* @param status status
|
||||
* @return this
|
||||
*/
|
||||
public EnumsTemplate status(Object... status) {
|
||||
return this.values(Const.STATUS, status);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
/**
|
||||
* 后端代码模板
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 1:14
|
||||
*/
|
||||
public class ServerTemplate extends Template {
|
||||
|
||||
public ServerTemplate(Table table) {
|
||||
super(table);
|
||||
table.enableUnitTest = true;
|
||||
}
|
||||
|
||||
public ServerTemplate(Table table, String tableName) {
|
||||
super(table);
|
||||
table.tableName = tableName;
|
||||
table.enableUnitTest = true;
|
||||
}
|
||||
|
||||
public ServerTemplate(Table table, String tableName, String comment, String bizPackage) {
|
||||
super(table);
|
||||
table.tableName = tableName;
|
||||
table.comment = comment;
|
||||
table.bizPackage = bizPackage;
|
||||
table.enableUnitTest = true;
|
||||
table.enableOperatorLog = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置表名称
|
||||
*
|
||||
* @param tableName tableName
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate tableName(String tableName) {
|
||||
table.tableName = tableName;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置业务注释
|
||||
*
|
||||
* @param comment comment
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate comment(String comment) {
|
||||
table.comment = comment;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置业务实体包名
|
||||
*
|
||||
* @param bizPackage bizPackage
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate bizPackage(String bizPackage) {
|
||||
table.bizPackage = bizPackage;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 是否生成对外 api
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate enableProviderApi() {
|
||||
table.enableProviderApi = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
// fixme
|
||||
/**
|
||||
* 生成导出
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate enableExport() {
|
||||
table.enableExport = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 不生成单元测试
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate disableUnitTest() {
|
||||
table.enableUnitTest = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
// fixme
|
||||
/**
|
||||
* 不生成操作日志
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public ServerTemplate disableOperatorLog() {
|
||||
table.enableUnitTest = false;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 cache
|
||||
*
|
||||
* @return cache
|
||||
*/
|
||||
public CacheTemplate cache() {
|
||||
return new CacheTemplate(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 cache
|
||||
*
|
||||
* @param key key
|
||||
* @return cache
|
||||
*/
|
||||
public CacheTemplate cache(String key) {
|
||||
return new CacheTemplate(table, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 cache
|
||||
*
|
||||
* @param key key
|
||||
* @param desc desc
|
||||
* @return cache
|
||||
*/
|
||||
public CacheTemplate cache(String key, String desc) {
|
||||
return new CacheTemplate(table, key, desc);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,127 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/7/17 10:44
|
||||
*/
|
||||
@Data
|
||||
public class Table {
|
||||
|
||||
// -------------------- 后端 --------------------
|
||||
|
||||
/**
|
||||
* 表名称
|
||||
*/
|
||||
protected String tableName;
|
||||
|
||||
/**
|
||||
* 业务注释
|
||||
*/
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* 业务实体包名
|
||||
* <p>
|
||||
* request dto 包
|
||||
*/
|
||||
protected String bizPackage;
|
||||
|
||||
/**
|
||||
* 是否生成对外 api
|
||||
*/
|
||||
protected boolean enableProviderApi;
|
||||
|
||||
/**
|
||||
* 是否生成单元测试
|
||||
*/
|
||||
protected boolean enableUnitTest;
|
||||
|
||||
/**
|
||||
* 是否生成导出
|
||||
*/
|
||||
protected boolean enableExport;
|
||||
|
||||
/**
|
||||
* 是否可缓存
|
||||
*/
|
||||
protected boolean enableCache;
|
||||
|
||||
/**
|
||||
* 是否生成操作日志
|
||||
*/
|
||||
protected boolean enableOperatorLog;
|
||||
|
||||
/**
|
||||
* 缓存的 key
|
||||
*/
|
||||
protected String cacheKey;
|
||||
|
||||
/**
|
||||
* 缓存描述
|
||||
*/
|
||||
protected String cacheDesc;
|
||||
|
||||
/**
|
||||
* 缓存是否会过期
|
||||
*/
|
||||
protected boolean cacheExpired;
|
||||
|
||||
/**
|
||||
* 缓存过期时间
|
||||
*/
|
||||
protected Integer cacheExpireTime;
|
||||
|
||||
/**
|
||||
* 缓存过期时间单位
|
||||
*/
|
||||
protected TimeUnit cacheExpireUnit;
|
||||
|
||||
// -------------------- 前端 --------------------
|
||||
|
||||
/**
|
||||
* 是否生成 vue 代码
|
||||
*/
|
||||
protected boolean enableVue;
|
||||
|
||||
/**
|
||||
* 模块 用于文件名称生成
|
||||
*/
|
||||
protected String module;
|
||||
|
||||
/**
|
||||
* 功能 用于文件名称生成
|
||||
*/
|
||||
protected String feature;
|
||||
|
||||
/**
|
||||
* 使用抽屉表单
|
||||
*/
|
||||
protected boolean enableDrawerForm;
|
||||
|
||||
/**
|
||||
* 列表可多选
|
||||
*/
|
||||
protected boolean enableRowSelection;
|
||||
|
||||
/**
|
||||
* 使用卡片视图
|
||||
*/
|
||||
protected boolean enableCardView;
|
||||
|
||||
/**
|
||||
* 生成的枚举文件
|
||||
*/
|
||||
protected List<VueEnum> enums;
|
||||
|
||||
protected Table() {
|
||||
this.enums = new ArrayList<>();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 代码生成模板
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 0:51
|
||||
*/
|
||||
@Data
|
||||
public class Template {
|
||||
|
||||
protected final Table table;
|
||||
|
||||
protected Template(Table table) {
|
||||
this.table = table;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模板
|
||||
*
|
||||
* @param tableName 表名称
|
||||
* @return Template
|
||||
*/
|
||||
public static ServerTemplate create(String tableName) {
|
||||
return new ServerTemplate(new Table(), tableName);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建模板
|
||||
*
|
||||
* @param tableName 表名称
|
||||
* @param comment 业务注释
|
||||
* @param bizPackage 业务包名
|
||||
* @return Template
|
||||
*/
|
||||
public static ServerTemplate create(String tableName, String comment, String bizPackage) {
|
||||
return new ServerTemplate(new Table(), tableName, comment, bizPackage);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 server
|
||||
*
|
||||
* @return ServerTemplate
|
||||
*/
|
||||
public ServerTemplate server() {
|
||||
return new ServerTemplate(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 vue
|
||||
*
|
||||
* @return vue
|
||||
*/
|
||||
public VueTemplate vue() {
|
||||
return new VueTemplate(table);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置 vue
|
||||
*
|
||||
* @param module 模块
|
||||
* @param feature 功能
|
||||
* @return vue
|
||||
*/
|
||||
public VueTemplate vue(String module, String feature) {
|
||||
return new VueTemplate(table, module, feature);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建
|
||||
*
|
||||
* @return table
|
||||
*/
|
||||
public Table build() {
|
||||
return table;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 枚举元数据
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 13:53
|
||||
*/
|
||||
@Data
|
||||
public class VueEnum {
|
||||
|
||||
/**
|
||||
* 替换的枚举字段 数据库/小驼峰
|
||||
*/
|
||||
protected String variable;
|
||||
|
||||
/**
|
||||
* 枚举类名 如果为空使用 field.propertyName + Enum
|
||||
*/
|
||||
protected String className;
|
||||
|
||||
/**
|
||||
* 枚举注释 如果为空使用 field.comment || className
|
||||
*/
|
||||
protected String comment;
|
||||
|
||||
/**
|
||||
* 枚举名称
|
||||
*/
|
||||
protected List<String> names;
|
||||
|
||||
/**
|
||||
* 枚举字段
|
||||
*/
|
||||
protected List<String> fields;
|
||||
|
||||
/**
|
||||
* 枚举值
|
||||
*/
|
||||
protected List<List<Object>> values;
|
||||
|
||||
public VueEnum(String variable) {
|
||||
this(variable, null);
|
||||
}
|
||||
|
||||
public VueEnum(String variable, String className) {
|
||||
this.className = className;
|
||||
this.variable = variable;
|
||||
this.names = new ArrayList<>();
|
||||
this.fields = new ArrayList<>();
|
||||
this.values = new ArrayList<>();
|
||||
}
|
||||
|
||||
public VueEnum(String variable, String className, String comment, List<String> names, List<String> fields, List<List<Object>> values) {
|
||||
this.variable = variable;
|
||||
this.className = className;
|
||||
this.comment = comment;
|
||||
this.names = names;
|
||||
this.fields = fields;
|
||||
this.values = values;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package com.orion.ops.framework.mybatis.core.generator.template;
|
||||
|
||||
/**
|
||||
* 前端代码模板
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/9/26 1:17
|
||||
*/
|
||||
public class VueTemplate extends Template {
|
||||
|
||||
public VueTemplate(Table table) {
|
||||
super(table);
|
||||
table.enableVue = true;
|
||||
}
|
||||
|
||||
public VueTemplate(Table table, String module, String feature) {
|
||||
super(table);
|
||||
table.enableVue = true;
|
||||
table.module = module;
|
||||
table.feature = feature;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置模块 用于文件名称生成
|
||||
*
|
||||
* @param module module
|
||||
* @return this
|
||||
*/
|
||||
public VueTemplate module(String module) {
|
||||
table.module = module;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置功能 用于文件名称生成
|
||||
*
|
||||
* @param feature feature
|
||||
* @return this
|
||||
*/
|
||||
public VueTemplate feature(String feature) {
|
||||
table.feature = feature;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用抽屉表单
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public VueTemplate enableDrawerForm() {
|
||||
table.enableDrawerForm = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 列表可多选
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public VueTemplate enableRowSelection() {
|
||||
table.enableRowSelection = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 启用卡片列表
|
||||
*
|
||||
* @return this
|
||||
*/
|
||||
public VueTemplate enableCardView() {
|
||||
table.enableCardView = true;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置枚举
|
||||
*
|
||||
* @param variable 枚举字段 数据库/小驼峰
|
||||
* @return enums
|
||||
*/
|
||||
public EnumsTemplate enums(String variable) {
|
||||
return new EnumsTemplate(table, variable);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置枚举
|
||||
*
|
||||
* @param variable 枚举字段 数据库/小驼峰
|
||||
* @param className className
|
||||
* @return enums
|
||||
*/
|
||||
public EnumsTemplate enums(String variable, String className) {
|
||||
return new EnumsTemplate(table, variable, className);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置枚举
|
||||
*
|
||||
* @param variable 枚举字段 数据库/小驼峰
|
||||
* @param enumClass 枚举类
|
||||
* @return enums
|
||||
*/
|
||||
public EnumsTemplate enums(String variable, Class<? extends Enum<?>> enumClass) {
|
||||
return new EnumsTemplate(table, variable, enumClass);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.io.Serializable;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 缓存对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}CacheDTO", description = "$!{table.comment} 缓存对象")
|
||||
public class ${type}CacheDTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
private Date updateTime;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String creator;
|
||||
|
||||
@Schema(description = "修改人")
|
||||
private String updater;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.orion.lang.define.cache.CacheKeyBuilder;
|
||||
import com.orion.lang.define.cache.CacheKeyDefine;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
/**
|
||||
* $!{table.comment}缓存 key
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
public interface ${type}CacheKeyDefine {
|
||||
|
||||
CacheKeyDefine $typeConst = new CacheKeyBuilder()
|
||||
.key("$cacheMeta.cacheKey")
|
||||
.desc("$cacheMeta.cacheDesc")
|
||||
.type(${type}CacheDTO.class)
|
||||
#if($cacheMeta.cacheExpired)
|
||||
.timeout($cacheMeta.cacheExpireTime, TimeUnit.$cacheMeta.cacheExpireUnit.name())
|
||||
#end
|
||||
.build();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
${httpComment} ${apiComment.create}
|
||||
POST {{baseUrl}}/${package.ModuleName}/${typeHyphen}/create
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
"${field.propertyName}": ""#if($foreach.hasNext),#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.updateById}
|
||||
PUT {{baseUrl}}/${package.ModuleName}/${typeHyphen}/update
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
#foreach($field in ${table.fields})
|
||||
"${field.propertyName}": ""#if($foreach.hasNext),#end
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.getById}
|
||||
GET {{baseUrl}}/${package.ModuleName}/${typeHyphen}/get?id=1
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.getByIdList}
|
||||
GET {{baseUrl}}/${package.ModuleName}/${typeHyphen}/batch-get?idList=1,2,3
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.queryList}
|
||||
POST {{baseUrl}}/${package.ModuleName}/${typeHyphen}/list
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
#foreach($field in ${table.fields})
|
||||
"${field.propertyName}": ""#if($foreach.hasNext),#end
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.queryPage}
|
||||
POST {{baseUrl}}/${package.ModuleName}/${typeHyphen}/query
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
"page": 1,
|
||||
"limit": 10,
|
||||
#foreach($field in ${table.fields})
|
||||
"${field.propertyName}": ""#if($foreach.hasNext),#end
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.deleteById}
|
||||
DELETE {{baseUrl}}/${package.ModuleName}/${typeHyphen}/delete?id=1
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.batchDelete}
|
||||
DELETE {{baseUrl}}/${package.ModuleName}/${typeHyphen}/batch-delete?idList=1,2,3
|
||||
Authorization: {{token}}
|
||||
|
||||
|
||||
${httpComment} ${apiComment.export}
|
||||
POST {{baseUrl}}/${package.ModuleName}/${typeHyphen}/export
|
||||
Content-Type: application/json
|
||||
Authorization: {{token}}
|
||||
|
||||
{
|
||||
#foreach($field in ${table.fields})
|
||||
"${field.propertyName}": ""#if($foreach.hasNext),#end
|
||||
#end
|
||||
}
|
||||
|
||||
|
||||
${httpComment}
|
||||
@@ -0,0 +1,130 @@
|
||||
package ${package.Controller};
|
||||
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.ops.framework.biz.operator.log.core.annotation.OperatorLog;
|
||||
import com.orion.ops.framework.common.validator.group.Page;
|
||||
import com.orion.ops.framework.log.core.annotation.IgnoreLog;
|
||||
import com.orion.ops.framework.log.core.enums.IgnoreLogMode;
|
||||
import com.orion.ops.framework.web.core.annotation.RestWrapper;
|
||||
import ${package.Service}.*;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
#if(${superControllerClassPackage})
|
||||
import ${superControllerClassPackage};
|
||||
#end
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.Parameter;
|
||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.security.access.prepost.PreAuthorize;
|
||||
import org.springframework.validation.annotation.Validated;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* $!{table.comment} api
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Tag(name = "${package.ModuleName} - $!{table.comment}服务")
|
||||
@Slf4j
|
||||
@Validated
|
||||
@RestWrapper
|
||||
@RestController
|
||||
@RequestMapping("/${package.ModuleName}/${typeHyphen}")
|
||||
@SuppressWarnings({"ELValidationInJSP", "SpringElInspection"})
|
||||
#if(${superControllerClass})
|
||||
public class ${table.controllerName} extends ${superControllerClass} {
|
||||
#else
|
||||
public class ${table.controllerName} {
|
||||
#end
|
||||
|
||||
@Resource
|
||||
private ${type}Service ${typeLower}Service;
|
||||
|
||||
@OperatorLog(${type}OperatorType.CREATE)
|
||||
@PostMapping("/create")
|
||||
@Operation(summary = "${apiComment.create}")
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:create')")
|
||||
public Long create${type}(@Validated @RequestBody ${type}CreateRequest request) {
|
||||
return ${typeLower}Service.create${type}(request);
|
||||
}
|
||||
|
||||
@OperatorLog(${type}OperatorType.UPDATE)
|
||||
@PutMapping("/update")
|
||||
@Operation(summary = "${apiComment.updateById}")
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:update')")
|
||||
public Integer update${type}(@Validated @RequestBody ${type}UpdateRequest request) {
|
||||
return ${typeLower}Service.update${type}ById(request);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/get")
|
||||
@Operation(summary = "${apiComment.getById}")
|
||||
@Parameter(name = "id", description = "id", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:query')")
|
||||
public ${type}VO get${type}(@RequestParam("id") Long id) {
|
||||
return ${typeLower}Service.get${type}ById(id);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@GetMapping("/batch-get")
|
||||
@Operation(summary = "${apiComment.getByIdList}")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:query')")
|
||||
public List<${type}VO> get${type}Batch(@RequestParam("idList") List<Long> idList) {
|
||||
return ${typeLower}Service.get${type}ByIdList(idList);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@PostMapping("/list")
|
||||
@Operation(summary = "${apiComment.queryList}")
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:query')")
|
||||
public List<${type}VO> get${type}List(@Validated @RequestBody ${type}QueryRequest request) {
|
||||
return ${typeLower}Service.get${type}List(request);
|
||||
}
|
||||
|
||||
@IgnoreLog(IgnoreLogMode.RET)
|
||||
@PostMapping("/query")
|
||||
@Operation(summary = "${apiComment.queryPage}")
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:query')")
|
||||
public DataGrid<${type}VO> get${type}Page(@Validated(Page.class) @RequestBody ${type}QueryRequest request) {
|
||||
return ${typeLower}Service.get${type}Page(request);
|
||||
}
|
||||
|
||||
@OperatorLog(${type}OperatorType.DELETE)
|
||||
@DeleteMapping("/delete")
|
||||
@Operation(summary = "${apiComment.deleteById}")
|
||||
@Parameter(name = "id", description = "id", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:delete')")
|
||||
public Integer delete${type}(@RequestParam("id") Long id) {
|
||||
return ${typeLower}Service.delete${type}ById(id);
|
||||
}
|
||||
|
||||
@OperatorLog(${type}OperatorType.DELETE)
|
||||
@DeleteMapping("/batch-delete")
|
||||
@Operation(summary = "${apiComment.batchDelete}")
|
||||
@Parameter(name = "idList", description = "idList", required = true)
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:delete')")
|
||||
public Integer batchDelete${type}(@RequestParam("idList") List<Long> idList) {
|
||||
return ${typeLower}Service.delete${type}ByIdList(idList);
|
||||
}
|
||||
|
||||
@OperatorLog(${type}OperatorType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@Operation(summary = "${apiComment.export}")
|
||||
@PreAuthorize("@ss.hasPermission('${package.ModuleName}:${typeHyphen}:export')")
|
||||
public void export${type}(@Validated @RequestBody ${type}QueryRequest request,
|
||||
HttpServletResponse response) throws IOException {
|
||||
${typeLower}Service.export${type}(request, response);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import ${package.Entity}.*;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 内部对象转换器
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Mapper
|
||||
public interface ${type}Convert {
|
||||
|
||||
${type}Convert MAPPER = Mappers.getMapper(${type}Convert.class);
|
||||
|
||||
${type}DO to(${type}CreateRequest request);
|
||||
|
||||
${type}DO to(${type}UpdateRequest request);
|
||||
|
||||
${type}DO to(${type}QueryRequest request);
|
||||
|
||||
${type}VO to(${type}DO domain);
|
||||
|
||||
${type}Export toExport(${type}DO domain);
|
||||
|
||||
List<${type}VO> to(List<${type}DO> list);
|
||||
|
||||
#if($cacheMeta.enableCache)
|
||||
${type}VO to(${type}CacheDTO cache);
|
||||
|
||||
${type}CacheDTO toCache(${type}DO domain);
|
||||
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package ${package.Entity};
|
||||
|
||||
import com.baomidou.mybatisplus.annotation.*;
|
||||
import com.orion.ops.framework.mybatis.core.domain.BaseDO;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 实体对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
#if(${table.convert})
|
||||
@TableName(value = "${schemaName}${table.name}", autoResultMap = true)
|
||||
#end
|
||||
@Schema(name = "${entity}", description = "$!{table.comment} 实体对象")
|
||||
#if(${superEntityClass})
|
||||
public class ${entity} extends ${superEntityClass}#if(${activeRecord})<${entity}>#end {
|
||||
#elseif(${entitySerialVersionUID})
|
||||
public class ${entity} implements Serializable {
|
||||
#else
|
||||
public class ${entity} {
|
||||
#end
|
||||
#if(${entitySerialVersionUID})
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
#end
|
||||
## ---------- BEGIN 字段循环遍历 ----------
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if(${field.keyFlag})
|
||||
#set($keyPropertyName=${field.propertyName})
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
#if(${field.keyFlag})
|
||||
## 主键
|
||||
#if(${field.keyIdentityFlag})
|
||||
@TableId(value = "${field.annotationColumnName}", type = IdType.AUTO)
|
||||
#elseif(!$null.isNull(${idType}) && "$!idType" != "")
|
||||
@TableId(value = "${field.annotationColumnName}", type = IdType.${idType})
|
||||
#elseif(${field.convert})
|
||||
@TableId("${field.annotationColumnName}")
|
||||
#end
|
||||
## 普通字段
|
||||
#elseif(${field.fill})
|
||||
## ----- 存在字段填充设置 -----
|
||||
#if(${field.convert})
|
||||
@TableField(value = "${field.annotationColumnName}", fill = FieldFill.${field.fill})
|
||||
#else
|
||||
@TableField(fill = FieldFill.${field.fill})
|
||||
#end
|
||||
#elseif(${field.convert})
|
||||
@TableField("${field.annotationColumnName}")
|
||||
#end
|
||||
## 乐观锁注解
|
||||
#if(${field.versionField})
|
||||
@Version
|
||||
#end
|
||||
## 逻辑删除注解
|
||||
#if(${field.logicDeleteField})
|
||||
@TableLogic
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.orion.lang.utils.time.Dates;
|
||||
import com.orion.office.excel.annotation.ExportField;
|
||||
import com.orion.office.excel.annotation.ExportSheet;
|
||||
import com.orion.office.excel.annotation.ExportTitle;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 导出对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@ExportTitle(title = ${type}Export.TITLE)
|
||||
@ExportSheet(name = "$!{table.comment}", filterHeader = true, freezeHeader = true, indexToSort = true)
|
||||
@Schema(name = "${type}Export", description = "$!{table.comment}导出对象")
|
||||
public class ${type}Export implements Serializable {
|
||||
|
||||
public static final String TITLE = "$!{table.comment}导出";
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
#if("$field.propertyType" == "Date")
|
||||
@ExportField(index = ${foreach.index}, header = "${field.comment}", width = 16, format = Dates.YMD_HMS)
|
||||
#else
|
||||
@ExportField(index = ${foreach.index}, header = "${field.comment}", width = 16)
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
@ExportField(index = $table.fields.size(), header = "创建时间", width = 16, format = Dates.YMD_HMS)
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
#set($updateTimeIndex=$table.fields.size() + 1)
|
||||
@Schema(description = "修改时间")
|
||||
@ExportField(index = $updateTimeIndex, header = "修改时间", width = 16, format = Dates.YMD_HMS)
|
||||
private Date updateTime;
|
||||
|
||||
#set($creatorIndex=$table.fields.size() + 2)
|
||||
@Schema(description = "创建人")
|
||||
@ExportField(index = $creatorIndex, header = "创建人", width = 16)
|
||||
private String creator;
|
||||
|
||||
#set($updaterIndex=$table.fields.size() + 3)
|
||||
@Schema(description = "修改人")
|
||||
@ExportField(index = $updaterIndex, header = "修改人", width = 16)
|
||||
private String updater;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 创建请求对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}CreateRequest", description = "$!{table.comment} 创建请求对象")
|
||||
public class ${type}CreateRequest implements Serializable {
|
||||
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
#if("$field.propertyType" == "String")
|
||||
@NotBlank
|
||||
#if("$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
@Size(max = $field.metaInfo.length)
|
||||
#end
|
||||
#else
|
||||
@NotNull
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
#if("$field.propertyType" == "Date")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import com.orion.ops.framework.common.entity.PageRequest;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 查询请求对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@EqualsAndHashCode(callSuper = true)
|
||||
@Schema(name = "${type}QueryRequest", description = "$!{table.comment} 查询请求对象")
|
||||
public class ${type}QueryRequest extends PageRequest {
|
||||
|
||||
@Schema(description = "搜索")
|
||||
private String searchValue;
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$field.propertyType" == "String" && "$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
@Size(max = $field.metaInfo.length)
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
#if("$field.propertyType" == "Date")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonFormat;
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 更新请求对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}UpdateRequest", description = "$!{table.comment} 更新请求对象")
|
||||
public class ${type}UpdateRequest implements Serializable {
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$field.propertyType" == "String")
|
||||
@NotBlank
|
||||
#if("$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
@Size(max = $field.metaInfo.length)
|
||||
#end
|
||||
#else
|
||||
@NotNull
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
#if("$field.propertyType" == "Date")
|
||||
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.*;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 视图响应对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}VO", description = "$!{table.comment} 视图响应对象")
|
||||
public class ${type}VO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
private Date updateTime;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String creator;
|
||||
|
||||
@Schema(description = "修改人")
|
||||
private String updater;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package ${package.Mapper};
|
||||
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import ${superMapperClassPackage};
|
||||
import ${package.Entity}.${entity};
|
||||
#if(${mapperAnnotationClass})
|
||||
import ${mapperAnnotationClass.name};
|
||||
#end
|
||||
|
||||
/**
|
||||
* $!{table.comment} Mapper 接口
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
#if(${mapperAnnotationClass})
|
||||
@${mapperAnnotationClass.simpleName}
|
||||
#end
|
||||
public interface ${table.mapperName} extends ${superMapperClass}<${entity}> {
|
||||
|
||||
/**
|
||||
* 获取查询条件
|
||||
*
|
||||
* @param entity entity
|
||||
* @return 查询条件
|
||||
*/
|
||||
default LambdaQueryWrapper<${entity}> queryCondition(${entity} entity) {
|
||||
return this.wrapper()
|
||||
#foreach($field in ${table.fields})
|
||||
.eq(${type}DO::get${field.capitalName}, entity.get${field.capitalName}())#if(!$foreach.hasNext);#end
|
||||
#end
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?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="${package.Mapper}.${table.mapperName}">
|
||||
|
||||
#if(${enableCache})
|
||||
<!-- 开启二级缓存 -->
|
||||
<cache type="${cacheClassName}"/>
|
||||
|
||||
#end
|
||||
#if(${baseResultMap})
|
||||
<!-- 通用查询映射结果 -->
|
||||
<resultMap id="BaseResultMap" type="${package.Entity}.${entity}">
|
||||
#foreach($field in ${table.fields})
|
||||
#if(${field.keyFlag})##生成主键排在第一位
|
||||
<id column="${field.name}" property="${field.propertyName}"/>
|
||||
#end
|
||||
#end
|
||||
#foreach($field in ${table.fields})
|
||||
#if(!${field.keyFlag})##生成普通字段
|
||||
<result column="${field.name}" property="${field.propertyName}"/>
|
||||
#end
|
||||
#end
|
||||
#foreach($field in ${table.commonFields})##生成公共字段
|
||||
<result column="${field.name}" property="${field.propertyName}"/>
|
||||
#end
|
||||
</resultMap>
|
||||
|
||||
#end
|
||||
#if(${baseColumnList})
|
||||
<!-- 通用查询结果列 -->
|
||||
<sql id="Base_Column_List">
|
||||
${table.fieldNames}, #foreach($field in ${table.commonFields})${field.columnName}#if($foreach.hasNext), #end#end
|
||||
</sql>
|
||||
|
||||
#end
|
||||
</mapper>
|
||||
@@ -0,0 +1,37 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.orion.ops.framework.biz.operator.log.core.annotation.Module;
|
||||
import com.orion.ops.framework.biz.operator.log.core.factory.InitializingOperatorTypes;
|
||||
import com.orion.ops.framework.biz.operator.log.core.model.OperatorType;
|
||||
|
||||
import static com.orion.ops.framework.biz.operator.log.core.enums.OperatorRiskLevel.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 操作日志类型
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Module("${package.ModuleName}:${typeHyphen}")
|
||||
public class ${type}OperatorType extends InitializingOperatorTypes {
|
||||
|
||||
public static final String CREATE = "${typeHyphen}:create";
|
||||
|
||||
public static final String UPDATE = "${typeHyphen}:update";
|
||||
|
||||
public static final String DELETE = "${typeHyphen}:delete";
|
||||
|
||||
public static final String EXPORT = "${typeHyphen}:export";
|
||||
|
||||
@Override
|
||||
public OperatorType[] types() {
|
||||
return new OperatorType[]{
|
||||
new OperatorType(L, CREATE, "创建$!{table.comment}"),
|
||||
new OperatorType(M, UPDATE, "更新$!{table.comment}"),
|
||||
new OperatorType(H, DELETE, "删除$!{table.comment}"),
|
||||
new OperatorType(M, EXPORT, "导出$!{table.comment}"),
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,278 @@
|
||||
package ${package.ServiceImpl};
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.lang.utils.Strings;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.office.excel.writer.exporting.ExcelExport;
|
||||
#if($cacheMeta.enableCache)
|
||||
import com.orion.ops.framework.common.constant.Const;
|
||||
#end
|
||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||
import com.orion.ops.framework.common.utils.FileNames;
|
||||
import com.orion.ops.framework.common.utils.Valid;
|
||||
#if($cacheMeta.enableCache)
|
||||
import com.orion.ops.framework.redis.core.utils.RedisMaps;
|
||||
#end
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
import ${package.Entity}.${entity};
|
||||
import ${package.Mapper}.${table.mapperName};
|
||||
import ${package.Service}.${table.serviceName};
|
||||
import com.orion.web.servlet.web.Servlets;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 服务实现类
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ${table.serviceImplName} implements ${table.serviceName} {
|
||||
|
||||
@Resource
|
||||
private ${type}DAO ${typeLower}DAO;
|
||||
|
||||
@Override
|
||||
public Long create${type}(${type}CreateRequest request) {
|
||||
log.info("${type}Service-create${type} request: {}", JSON.toJSONString(request));
|
||||
// 转换
|
||||
${type}DO record = ${type}Convert.MAPPER.to(request);
|
||||
// 查询数据是否冲突
|
||||
this.check${type}Present(record);
|
||||
// 插入
|
||||
int effect = ${typeLower}DAO.insert(record);
|
||||
Long id = record.getId();
|
||||
log.info("${type}Service-create${type} id: {}, effect: {}", id, effect);
|
||||
#if($cacheMeta.enableCache)
|
||||
// 删除缓存
|
||||
RedisMaps.delete(${type}CacheKeyDefine.${typeConst});
|
||||
#end
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer update${type}ById(${type}UpdateRequest request) {
|
||||
Long id = Valid.notNull(request.getId(), ErrorMessage.ID_MISSING);
|
||||
log.info("${type}Service-update${type}ById id: {}, request: {}", id, JSON.toJSONString(request));
|
||||
// 查询
|
||||
${type}DO record = ${typeLower}DAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 转换
|
||||
${type}DO updateRecord = ${type}Convert.MAPPER.to(request);
|
||||
// 查询数据是否冲突
|
||||
this.check${type}Present(updateRecord);
|
||||
// 更新
|
||||
int effect = ${typeLower}DAO.updateById(updateRecord);
|
||||
log.info("${type}Service-update${type}ById effect: {}", effect);
|
||||
#if($cacheMeta.enableCache)
|
||||
// 删除缓存
|
||||
RedisMaps.delete(${type}CacheKeyDefine.${typeConst});
|
||||
#end
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer update${type}(${type}QueryRequest query, ${type}UpdateRequest update) {
|
||||
log.info("${type}Service.update${type} query: {}, update: {}", JSON.toJSONString(query), JSON.toJSONString(update));
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(query);
|
||||
// 转换
|
||||
${type}DO updateRecord = ${type}Convert.MAPPER.to(update);
|
||||
// 更新
|
||||
int effect = ${typeLower}DAO.update(updateRecord, wrapper);
|
||||
log.info("${type}Service.update${type} effect: {}", effect);
|
||||
#if($cacheMeta.enableCache)
|
||||
// 删除缓存
|
||||
RedisMaps.delete(${type}CacheKeyDefine.${typeConst});
|
||||
#end
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ${type}VO get${type}ById(Long id) {
|
||||
// 查询
|
||||
${type}DO record = ${typeLower}DAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 转换
|
||||
return ${type}Convert.MAPPER.to(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<${type}VO> get${type}ByIdList(List<Long> idList) {
|
||||
// 查询
|
||||
List<${type}DO> records = ${typeLower}DAO.selectBatchIds(idList);
|
||||
if (records.isEmpty()) {
|
||||
return Lists.empty();
|
||||
}
|
||||
// 转换
|
||||
return ${type}Convert.MAPPER.to(records);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<${type}VO> get${type}List(${type}QueryRequest request) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
|
||||
// 查询
|
||||
return ${typeLower}DAO.of(wrapper).list(${type}Convert.MAPPER::to);
|
||||
}
|
||||
|
||||
#if($cacheMeta.enableCache)
|
||||
@Override
|
||||
public List<${type}VO> get${type}ListByCache() {
|
||||
// 查询缓存
|
||||
List<${type}CacheDTO> list = RedisMaps.valuesJson(${type}CacheKeyDefine.${typeConst});
|
||||
if (list.isEmpty()) {
|
||||
// 查询数据库
|
||||
list = ${typeLower}DAO.of().list(${type}Convert.MAPPER::toCache);
|
||||
// 添加默认值 防止穿透
|
||||
if (list.isEmpty()) {
|
||||
list.add(${type}CacheDTO.builder()
|
||||
.id(Const.NONE_ID)
|
||||
.build());
|
||||
}
|
||||
// 设置缓存
|
||||
RedisMaps.putAllJson(${type}CacheKeyDefine.${typeConst}.getKey(), s -> s.getId().toString(), list);
|
||||
RedisMaps.setExpire(${type}CacheKeyDefine.${typeConst});
|
||||
}
|
||||
// 删除默认值
|
||||
return list.stream()
|
||||
.filter(s -> !s.getId().equals(Const.NONE_ID))
|
||||
.map(${type}Convert.MAPPER::to)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
#end
|
||||
@Override
|
||||
public Long get${type}Count(${type}QueryRequest request) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
|
||||
// 查询
|
||||
return ${typeLower}DAO.selectCount(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataGrid<${type}VO> get${type}Page(${type}QueryRequest request) {
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
|
||||
// 查询
|
||||
return ${typeLower}DAO.of(wrapper)
|
||||
.page(request)
|
||||
.dataGrid(${type}Convert.MAPPER::to);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete${type}ById(Long id) {
|
||||
log.info("${type}Service-delete${type}ById id: {}", id);
|
||||
// 检查数据是否存在
|
||||
${type}DO record = ${typeLower}DAO.selectById(id);
|
||||
Valid.notNull(record, ErrorMessage.DATA_ABSENT);
|
||||
// 删除
|
||||
int effect = ${typeLower}DAO.deleteById(id);
|
||||
log.info("${type}Service-delete${type}ById id: {}, effect: {}", id, effect);
|
||||
#if($cacheMeta.enableCache)
|
||||
// 删除缓存
|
||||
RedisMaps.delete(${type}CacheKeyDefine.${typeConst}, id);
|
||||
#end
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete${type}ByIdList(List<Long> idList) {
|
||||
log.info("${type}Service-delete${type}ByIdList idList: {}", idList);
|
||||
int effect = ${typeLower}DAO.deleteBatchIds(idList);
|
||||
log.info("${type}Service-delete${type}ByIdList effect: {}", effect);
|
||||
#if($cacheMeta.enableCache)
|
||||
// 删除缓存
|
||||
RedisMaps.delete(${type}CacheKeyDefine.${typeConst}, idList);
|
||||
#end
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete${type}(${type}QueryRequest request) {
|
||||
log.info("${type}Service.delete${type} request: {}", JSON.toJSONString(request));
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
|
||||
// 删除
|
||||
int effect = ${typeLower}DAO.delete(wrapper);
|
||||
log.info("${type}Service.delete${type} effect: {}", effect);
|
||||
#if($cacheMeta.enableCache)
|
||||
// 删除缓存
|
||||
RedisMaps.delete(${type}CacheKeyDefine.${typeConst});
|
||||
#end
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void export${type}(${type}QueryRequest request, HttpServletResponse response) throws IOException {
|
||||
log.info("${type}Service.export${type} request: {}", JSON.toJSONString(request));
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(request);
|
||||
// 查询
|
||||
List<${type}Export> rows = ${typeLower}DAO.of(wrapper).list(${type}Convert.MAPPER::toExport);
|
||||
log.info("${type}Service.export${type} size: {}", rows.size());
|
||||
// 导出
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
ExcelExport.create(${type}Export.class)
|
||||
.addRows(rows)
|
||||
.write(out)
|
||||
.close();
|
||||
// 传输
|
||||
Servlets.transfer(response, out.toByteArray(), FileNames.exportName(${type}Export.TITLE));
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查对象是否存在
|
||||
*
|
||||
* @param domain domain
|
||||
*/
|
||||
private void check${type}Present(${type}DO domain) {
|
||||
// 构造条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = ${typeLower}DAO.wrapper()
|
||||
// 更新时忽略当前记录
|
||||
.ne(${type}DO::getId, domain.getId())
|
||||
// 用其他字段做重复校验
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
.eq(${type}DO::get${field.capitalName}, domain.get${field.capitalName}())#if(!$foreach.hasNext);#end
|
||||
#end
|
||||
#end
|
||||
// 检查是否存在
|
||||
boolean present = ${typeLower}DAO.of(wrapper).present();
|
||||
Valid.isFalse(present, ErrorMessage.DATA_PRESENT);
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询 wrapper
|
||||
*
|
||||
* @param request request
|
||||
* @return wrapper
|
||||
*/
|
||||
private LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryRequest request) {
|
||||
String searchValue = request.getSearchValue();
|
||||
return ${typeLower}DAO.wrapper()
|
||||
#foreach($field in ${table.fields})
|
||||
.eq(${type}DO::get${field.capitalName}, request.get${field.capitalName}())
|
||||
#end
|
||||
.and(Strings.isNotEmpty(searchValue), c -> c
|
||||
#foreach($field in ${table.fields})
|
||||
.eq(${type}DO::get${field.capitalName}, searchValue)#if($foreach.hasNext).or()#end
|
||||
#end
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
package ${package.Service};
|
||||
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 服务类
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
public interface ${table.serviceName} {
|
||||
|
||||
/**
|
||||
* ${apiComment.create}
|
||||
*
|
||||
* @param request request
|
||||
* @return id
|
||||
*/
|
||||
Long create${type}(${type}CreateRequest request);
|
||||
|
||||
/**
|
||||
* ${apiComment.updateById}
|
||||
*
|
||||
* @param request request
|
||||
* @return effect
|
||||
*/
|
||||
Integer update${type}ById(${type}UpdateRequest request);
|
||||
|
||||
/**
|
||||
* ${apiComment.updateAll}
|
||||
*
|
||||
* @param query query
|
||||
* @param update update
|
||||
* @return effect
|
||||
*/
|
||||
Integer update${type}(${type}QueryRequest query, ${type}UpdateRequest update);
|
||||
|
||||
/**
|
||||
* ${apiComment.getById}
|
||||
*
|
||||
* @param id id
|
||||
* @return row
|
||||
*/
|
||||
${type}VO get${type}ById(Long id);
|
||||
|
||||
/**
|
||||
* ${apiComment.getByIdList}
|
||||
*
|
||||
* @param idList idList
|
||||
* @return rows
|
||||
*/
|
||||
List<${type}VO> get${type}ByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* ${apiComment.queryList}
|
||||
*
|
||||
* @param request request
|
||||
* @return rows
|
||||
*/
|
||||
List<${type}VO> get${type}List(${type}QueryRequest request);
|
||||
|
||||
#if($cacheMeta.enableCache)
|
||||
/**
|
||||
* ${apiComment.queryListByCache}
|
||||
*
|
||||
* @return rows
|
||||
*/
|
||||
List<${type}VO> get${type}ListByCache();
|
||||
|
||||
#end
|
||||
/**
|
||||
* ${apiComment.queryCount}
|
||||
*
|
||||
* @param request request
|
||||
* @return count
|
||||
*/
|
||||
Long get${type}Count(${type}QueryRequest request);
|
||||
|
||||
/**
|
||||
* ${apiComment.queryPage}
|
||||
*
|
||||
* @param request request
|
||||
* @return rows
|
||||
*/
|
||||
DataGrid<${type}VO> get${type}Page(${type}QueryRequest request);
|
||||
|
||||
/**
|
||||
* ${apiComment.deleteById}
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}ById(Long id);
|
||||
|
||||
/**
|
||||
* ${apiComment.batchDelete}
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}ByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* ${apiComment.deleteAll}
|
||||
*
|
||||
* @param request request
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}(${type}QueryRequest request);
|
||||
|
||||
/**
|
||||
* ${apiComment.export}
|
||||
*
|
||||
* @param request request
|
||||
* @param response response
|
||||
* @throws IOException IOException
|
||||
*/
|
||||
void export${type}(${type}QueryRequest request, HttpServletResponse response) throws IOException;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,172 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.alibaba.fastjson.JSON;
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.ops.framework.common.constant.ErrorMessage;
|
||||
import com.orion.ops.framework.common.utils.Valid;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
#foreach($pkg in ${customProviderFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
import ${package.Entity}.${entity};
|
||||
import ${package.Mapper}.${table.mapperName};
|
||||
import ${package.Service}.${table.serviceName};
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 对外服务实现类
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Slf4j
|
||||
@Service
|
||||
public class ${type}ApiImpl implements ${type}Api {
|
||||
|
||||
@Resource
|
||||
private ${type}Service ${typeLower}Service;
|
||||
|
||||
@Resource
|
||||
private ${type}DAO ${typeLower}DAO;
|
||||
|
||||
@Override
|
||||
public Long create${type}(${type}CreateDTO dto) {
|
||||
log.info("${type}Api.create${type} dto: {}", JSON.toJSONString(dto));
|
||||
Valid.valid(dto);
|
||||
// 转换
|
||||
${type}CreateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto);
|
||||
// 创建
|
||||
return ${typeLower}Service.create${type}(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer update${type}ById(${type}UpdateDTO dto) {
|
||||
log.info("${type}Api.update${type}ById dto: {}", JSON.toJSONString(dto));
|
||||
Valid.valid(dto);
|
||||
// 转换
|
||||
${type}UpdateRequest request = ${type}ProviderConvert.MAPPER.toRequest(dto);
|
||||
// 修改
|
||||
return ${typeLower}Service.update${type}ById(request);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer update${type}(${type}QueryDTO query, ${type}UpdateDTO update) {
|
||||
log.info("${type}Api.update${type} query: {}, update: {}", JSON.toJSONString(query), JSON.toJSONString(update));
|
||||
Valid.valid(query);
|
||||
Valid.valid(update);
|
||||
// 更新
|
||||
int effect = ${typeLower}Service.update${type}(${type}ProviderConvert.MAPPER.toRequest(query),
|
||||
${type}ProviderConvert.MAPPER.toRequest(update));
|
||||
log.info("${type}Api.update${type} effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ${type}DTO get${type}ById(Long id) {
|
||||
log.info("${type}Api.get${type}ById id: {}", id);
|
||||
Valid.notNull(id, ErrorMessage.ID_MISSING);
|
||||
// 修改
|
||||
${type}DO record = ${typeLower}DAO.selectById(id);
|
||||
if (record == null) {
|
||||
return null;
|
||||
}
|
||||
// 转换
|
||||
return ${type}ProviderConvert.MAPPER.to(record);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<${type}DTO> get${type}ByIdList(List<Long> idList) {
|
||||
log.info("${type}Api.get${type}ByIdList idList: {}", idList);
|
||||
if (Lists.isEmpty(idList)) {
|
||||
return new ArrayList<>();
|
||||
}
|
||||
// 查询
|
||||
List<${type}DO> rows = ${typeLower}DAO.selectBatchIds(idList);
|
||||
// 转换
|
||||
return ${type}ProviderConvert.MAPPER.toList(rows);
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<${type}DTO> get${type}List(${type}QueryDTO dto) {
|
||||
log.info("${type}Api.get${type}List dto: {}", JSON.toJSONString(dto));
|
||||
Valid.valid(dto);
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(dto);
|
||||
// 查询
|
||||
return ${typeLower}DAO.of(wrapper).list(${type}ProviderConvert.MAPPER::to);
|
||||
}
|
||||
|
||||
#if($cacheMeta.enableCache)
|
||||
@Override
|
||||
public List<${type}DTO> get${type}ListByCache() {
|
||||
return ${typeLower}Service.get${type}ListByCache()
|
||||
.stream()
|
||||
.map(${type}ProviderConvert.MAPPER::to)
|
||||
.collect(Collectors.toList());
|
||||
}
|
||||
|
||||
#end
|
||||
@Override
|
||||
public Long get${type}Count(${type}QueryDTO dto) {
|
||||
log.info("${type}Api.get${type}Count dto: {}", JSON.toJSONString(dto));
|
||||
Valid.valid(dto);
|
||||
// 条件
|
||||
LambdaQueryWrapper<${type}DO> wrapper = this.buildQueryWrapper(dto);
|
||||
// 查询
|
||||
return ${typeLower}DAO.selectCount(wrapper);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete${type}ById(Long id) {
|
||||
log.info("${type}Api.delete${type}ById id: {}", id);
|
||||
Valid.notNull(id, ErrorMessage.ID_MISSING);
|
||||
// 删除
|
||||
Integer effect = ${typeLower}Service.delete${type}ById(id);
|
||||
log.info("${type}Api.delete${type}ById id: {}, effect: {}", id, effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete${type}ByIdList(List<Long> idList) {
|
||||
log.info("${type}Api.delete${type}ByIdList idList: {}", idList);
|
||||
Valid.notEmpty(idList, ErrorMessage.ID_MISSING);
|
||||
// 删除
|
||||
Integer effect = ${typeLower}Service.delete${type}ByIdList(idList);
|
||||
log.info("${type}Api.delete${type}ByIdList effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Integer delete${type}(${type}QueryDTO dto) {
|
||||
log.info("${type}Api.delete${type} dto: {}", JSON.toJSONString(dto));
|
||||
Valid.valid(dto);
|
||||
// 删除
|
||||
Integer effect = ${typeLower}Service.delete${type}(${type}ProviderConvert.MAPPER.toRequest(dto));
|
||||
log.info("${type}Api.delete${type} effect: {}", effect);
|
||||
return effect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 构建查询 wrapper
|
||||
*
|
||||
* @param dto dto
|
||||
* @return wrapper
|
||||
*/
|
||||
private LambdaQueryWrapper<${type}DO> buildQueryWrapper(${type}QueryDTO dto) {
|
||||
return ${typeLower}DAO.wrapper()
|
||||
#foreach($field in ${table.fields})
|
||||
.eq(${type}DO::get${field.capitalName}, dto.get${field.capitalName}())#if(!$foreach.hasNext);#end
|
||||
#end
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
package ${currentPackage};
|
||||
|
||||
#foreach($pkg in ${customProviderEntityFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 对外服务类
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
public interface ${type}Api {
|
||||
|
||||
/**
|
||||
* ${apiComment.create}
|
||||
*
|
||||
* @param dto dto
|
||||
* @return id
|
||||
*/
|
||||
Long create${type}(${type}CreateDTO dto);
|
||||
|
||||
/**
|
||||
* ${apiComment.updateById}
|
||||
*
|
||||
* @param dto dto
|
||||
* @return effect
|
||||
*/
|
||||
Integer update${type}ById(${type}UpdateDTO dto);
|
||||
|
||||
/**
|
||||
* ${apiComment.updateAll}
|
||||
*
|
||||
* @param query query
|
||||
* @param update update
|
||||
* @return effect
|
||||
*/
|
||||
Integer update${type}(${type}QueryDTO query, ${type}UpdateDTO update);
|
||||
|
||||
/**
|
||||
* ${apiComment.getById}
|
||||
*
|
||||
* @param id id
|
||||
* @return row
|
||||
*/
|
||||
${type}DTO get${type}ById(Long id);
|
||||
|
||||
/**
|
||||
* ${apiComment.getByIdList}
|
||||
*
|
||||
* @param idList idList
|
||||
* @return rows
|
||||
*/
|
||||
List<${type}DTO> get${type}ByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* ${apiComment.queryList}
|
||||
*
|
||||
* @param dto dto
|
||||
* @return rows
|
||||
*/
|
||||
List<${type}DTO> get${type}List(${type}QueryDTO dto);
|
||||
|
||||
#if($cacheMeta.enableCache)
|
||||
/**
|
||||
* ${apiComment.queryListByCache}
|
||||
*
|
||||
* @return rows
|
||||
*/
|
||||
List<${type}DTO> get${type}ListByCache();
|
||||
|
||||
#end
|
||||
/**
|
||||
* ${apiComment.queryCount}
|
||||
*
|
||||
* @param dto dto
|
||||
* @return count
|
||||
*/
|
||||
Long get${type}Count(${type}QueryDTO dto);
|
||||
|
||||
/**
|
||||
* ${apiComment.deleteById}
|
||||
*
|
||||
* @param id id
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}ById(Long id);
|
||||
|
||||
/**
|
||||
* ${apiComment.batchDelete}
|
||||
*
|
||||
* @param idList idList
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}ByIdList(List<Long> idList);
|
||||
|
||||
/**
|
||||
* ${apiComment.deleteAll}
|
||||
*
|
||||
* @param dto dto
|
||||
* @return effect
|
||||
*/
|
||||
Integer delete${type}(${type}QueryDTO dto);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import ${package.Entity}.*;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
#foreach($pkg in ${customProviderEntityFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
import org.mapstruct.Mapper;
|
||||
import org.mapstruct.factory.Mappers;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 对外服务对象转换器
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Mapper
|
||||
public interface ${type}ProviderConvert {
|
||||
|
||||
${type}ProviderConvert MAPPER = Mappers.getMapper(${type}ProviderConvert.class);
|
||||
|
||||
${type}DTO to(${type}VO dto);
|
||||
|
||||
${type}DO to(${type}DTO dto);
|
||||
|
||||
${type}DTO to(${type}DO domain);
|
||||
|
||||
${type}DO to(${type}QueryDTO domain);
|
||||
|
||||
${type}DO to(${type}UpdateDTO update);
|
||||
|
||||
${type}QueryRequest toRequest(${type}QueryDTO request);
|
||||
|
||||
${type}CreateRequest toRequest(${type}CreateDTO request);
|
||||
|
||||
${type}UpdateRequest toRequest(${type}UpdateDTO request);
|
||||
|
||||
List<${type}DTO> toList(List<${type}DO> list);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 创建请求业务对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}CreateDTO", description = "$!{table.comment} 创建请求业务对象")
|
||||
public class ${type}CreateDTO implements Serializable {
|
||||
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
#if("$field.propertyType" == "String")
|
||||
@NotBlank
|
||||
#if("$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
@Size(max = $field.metaInfo.length)
|
||||
#end
|
||||
#else
|
||||
@NotNull
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
|
||||
#end
|
||||
#end
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 查询请求业务对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}QueryDTO", description = "$!{table.comment} 查询请求业务对象")
|
||||
public class ${type}QueryDTO implements Serializable {
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$field.propertyType" == "String" && "$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
@Size(max = $field.metaInfo.length)
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
|
||||
import javax.validation.constraints.NotBlank;
|
||||
import javax.validation.constraints.NotNull;
|
||||
import javax.validation.constraints.Size;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 更新请求业务对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}UpdateDTO", description = "$!{table.comment} 更新请求业务对象")
|
||||
public class ${type}UpdateDTO implements Serializable {
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$field.propertyType" == "String")
|
||||
@NotBlank
|
||||
#if("$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
@Size(max = $field.metaInfo.length)
|
||||
#end
|
||||
#else
|
||||
@NotNull
|
||||
#end
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import io.swagger.v3.oas.annotations.media.Schema;
|
||||
import java.io.Serializable;
|
||||
import lombok.*;
|
||||
|
||||
import java.util.*;
|
||||
import java.math.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 业务对象
|
||||
*
|
||||
* @author ${author}
|
||||
* @version ${since}
|
||||
* @since ${date}
|
||||
*/
|
||||
@Data
|
||||
@Builder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
@Schema(name = "${type}DTO", description = "$!{table.comment} 业务对象")
|
||||
public class ${type}DTO implements Serializable {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
#foreach($field in ${table.fields})
|
||||
|
||||
#if("$!field.comment" != "")
|
||||
@Schema(description = "${field.comment}")
|
||||
#end
|
||||
private ${field.propertyType} ${field.propertyName};
|
||||
#end
|
||||
|
||||
@Schema(description = "创建时间")
|
||||
private Date createTime;
|
||||
|
||||
@Schema(description = "修改时间")
|
||||
private Date updateTime;
|
||||
|
||||
@Schema(description = "创建人")
|
||||
private String creator;
|
||||
|
||||
@Schema(description = "修改人")
|
||||
private String updater;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,126 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.ops.framework.test.core.base.BaseUnitTest;
|
||||
import com.orion.ops.framework.test.core.utils.EntityRandoms;
|
||||
import ${package.ServiceImpl}.*;
|
||||
#foreach($pkg in ${customProviderFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 对外服务单元测试
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/8/23 10:36
|
||||
*/
|
||||
@Slf4j
|
||||
@Import({${type}ApiImpl.class, ${type}ServiceImpl.class})
|
||||
public class ${type}ApiImplTests extends BaseUnitTest {
|
||||
|
||||
@Resource
|
||||
private ${type}Api ${typeLower}Api;
|
||||
|
||||
private static Long lastId;
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void create${type}Test() {
|
||||
${type}CreateDTO req = EntityRandoms.random(${type}CreateDTO.class);
|
||||
lastId = ${typeLower}Api.create${type}(req);
|
||||
assertNotNull(lastId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void update${type}ByIdTest() {
|
||||
${type}UpdateDTO req = EntityRandoms.random(${type}UpdateDTO.class);
|
||||
req.setId(lastId);
|
||||
Integer effect = ${typeLower}Api.update${type}ById(req);
|
||||
assertEquals(effect, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
public void update${type}Test() {
|
||||
${type}QueryDTO query = new ${type}QueryDTO();
|
||||
query.setId(lastId);
|
||||
${type}UpdateDTO req = EntityRandoms.random(${type}UpdateDTO.class);
|
||||
req.setId(null);
|
||||
Integer effect = ${typeLower}Api.update${type}(query, req);
|
||||
assertEquals(effect, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void get${type}ByIdTest() {
|
||||
${type}DTO row = ${typeLower}Api.get${type}ById(lastId);
|
||||
assertNotNull(row);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
public void get${type}ByIdListTest() {
|
||||
List<${type}DTO> rows = ${typeLower}Api.get${type}ByIdList(Lists.of(lastId));
|
||||
assertFalse(rows.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void get${type}ListTest() {
|
||||
List<${type}DTO> rows = ${typeLower}Api.get${type}List(new ${type}QueryDTO());
|
||||
assertFalse(rows.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void get${type}CountTest() {
|
||||
Long count = ${typeLower}Api.get${type}Count(new ${type}QueryDTO());
|
||||
assertEquals(count, 1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(8)
|
||||
public void delete${type}ByIdTest() {
|
||||
Integer effect = ${typeLower}Api.delete${type}ById(lastId);
|
||||
assertEquals(effect, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(9)
|
||||
public void delete${type}ByIdListTest() {
|
||||
Integer effect = ${typeLower}Api.delete${type}ByIdList(Lists.of(lastId));
|
||||
assertEquals(effect, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(10)
|
||||
public void delete${type}Test() {
|
||||
${type}QueryDTO dto = new ${type}QueryDTO();
|
||||
Integer effect = ${typeLower}Api.delete${type}(dto);
|
||||
assertEquals(effect, 0);
|
||||
}
|
||||
#if($cacheMeta.enableCache)
|
||||
|
||||
// -------------------- cache --------------------
|
||||
|
||||
@Test
|
||||
@Order(11)
|
||||
public void get${type}ListByCacheTest() {
|
||||
this.create${type}Test();
|
||||
List<${type}DTO> list = ${typeLower}Api.get${type}ListByCache();
|
||||
assertEquals(list.size(), 1);
|
||||
}
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
-- $!{table.comment}
|
||||
DROP TABLE IF EXISTS `${table.name}`;
|
||||
CREATE TABLE `${table.name}`
|
||||
(
|
||||
`id` BIGINT NOT NULL AUTO_INCREMENT COMMENT 'id',
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
#if("$field.metaInfo.jdbcType" == "TINYINT" || "$field.metaInfo.jdbcType" == "SMALLINT" || "$field.metaInfo.jdbcType" == "INTEGER" || "$field.metaInfo.jdbcType" == "BIGINT" || "$field.metaInfo.jdbcType" == "FLOAT" || "$field.metaInfo.jdbcType" == "DOUBLE" || "$field.metaInfo.jdbcType" == "NUMERIC" || "$field.metaInfo.jdbcType" == "LONGVARCHAR" || "$field.metaInfo.jdbcType" == "DATE" || "$field.metaInfo.jdbcType" == "TIME" || "$field.metaInfo.jdbcType" == "TIMESTAMP")
|
||||
`${field.columnName}` ${field.metaInfo.jdbcType}#if(!$field.metaInfo.nullable) NOT NULL#end#if($null.isNull($field.metaInfo.defaultValue) || "$!{field.metaInfo.defaultValue}" == "") DEFAULT NULL#else DEFAULT#if(${field.propertyType} == 'String') '${field.metaInfo.defaultValue}'#else ${field.metaInfo.defaultValue}#end#end COMMENT '$!{field.metaInfo.remarks}',
|
||||
#else
|
||||
`${field.columnName}` ${field.metaInfo.jdbcType}(${field.metaInfo.length})#if(!$field.metaInfo.nullable) NOT NULL#end#if($null.isNull($field.metaInfo.defaultValue) || "$!{field.metaInfo.defaultValue}" == "") DEFAULT NULL#else DEFAULT#if(${field.propertyType} == 'String') '${field.metaInfo.defaultValue}'#else ${field.metaInfo.defaultValue}#end#end COMMENT '$!{field.metaInfo.remarks}',
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
|
||||
`update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
|
||||
`creator` VARCHAR(64) DEFAULT NULL COMMENT '创建人',
|
||||
`updater` VARCHAR(64) DEFAULT NULL COMMENT '更新人',
|
||||
`deleted` TINYINT DEFAULT '0' COMMENT '是否删除 0未删除 1已删除',
|
||||
PRIMARY KEY (`id`)
|
||||
);
|
||||
@@ -0,0 +1,137 @@
|
||||
package ${currentPackage};
|
||||
|
||||
import com.orion.lang.define.wrapper.DataGrid;
|
||||
import com.orion.lang.utils.collect.Lists;
|
||||
import com.orion.ops.framework.test.core.base.BaseUnitTest;
|
||||
import com.orion.ops.framework.test.core.utils.EntityRandoms;
|
||||
import ${package.Service}.*;
|
||||
#foreach($pkg in ${customModuleFilePackages})
|
||||
import ${pkg}.*;
|
||||
#end
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.junit.jupiter.api.Order;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
/**
|
||||
* $!{table.comment} 服务单元测试
|
||||
*
|
||||
* @author Jiahang Li
|
||||
* @version 1.0.0
|
||||
* @since 2023/8/23 10:36
|
||||
*/
|
||||
@Slf4j
|
||||
@Import(${type}ServiceImpl.class)
|
||||
public class ${type}ServiceImplTests extends BaseUnitTest {
|
||||
|
||||
@Resource
|
||||
private ${type}Service ${typeLower}Service;
|
||||
|
||||
private static Long lastId;
|
||||
|
||||
@Test
|
||||
@Order(1)
|
||||
public void create${type}Test() {
|
||||
${type}CreateRequest req = EntityRandoms.random(${type}CreateRequest.class);
|
||||
lastId = ${typeLower}Service.create${type}(req);
|
||||
assertNotNull(lastId);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(2)
|
||||
public void update${type}ByIdTest() {
|
||||
${type}UpdateRequest req = EntityRandoms.random(${type}UpdateRequest.class);
|
||||
req.setId(lastId);
|
||||
Integer effect = ${typeLower}Service.update${type}ById(req);
|
||||
assertEquals(effect, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(3)
|
||||
public void update${type}Test() {
|
||||
${type}QueryRequest query = new ${type}QueryRequest();
|
||||
query.setId(lastId);
|
||||
${type}UpdateRequest req = EntityRandoms.random(${type}UpdateRequest.class);
|
||||
req.setId(null);
|
||||
Integer effect = ${typeLower}Service.update${type}(query, req);
|
||||
assertEquals(effect, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(4)
|
||||
public void get${type}ByIdTest() {
|
||||
${type}VO row = ${typeLower}Service.get${type}ById(lastId);
|
||||
assertNotNull(row);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(5)
|
||||
public void get${type}ByIdListTest() {
|
||||
List<${type}VO> rows = ${typeLower}Service.get${type}ByIdList(Lists.of(lastId));
|
||||
assertFalse(rows.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(6)
|
||||
public void get${type}ListTest() {
|
||||
List<${type}VO> rows = ${typeLower}Service.get${type}List(new ${type}QueryRequest());
|
||||
assertFalse(rows.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(7)
|
||||
public void get${type}CountTest() {
|
||||
Long count = ${typeLower}Service.get${type}Count(new ${type}QueryRequest());
|
||||
assertEquals(count, 1L);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(8)
|
||||
public void get${type}PageTest() {
|
||||
${type}QueryRequest request = new ${type}QueryRequest();
|
||||
request.setPage(1);
|
||||
request.setLimit(1);
|
||||
DataGrid<${type}VO> dataGrid = ${typeLower}Service.get${type}Page(request);
|
||||
assertFalse(dataGrid.isEmpty());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(9)
|
||||
public void delete${type}ByIdTest() {
|
||||
Integer effect = ${typeLower}Service.delete${type}ById(lastId);
|
||||
assertEquals(effect, 1);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(10)
|
||||
public void delete${type}ByIdListTest() {
|
||||
Integer effect = ${typeLower}Service.delete${type}ByIdList(Lists.of(lastId));
|
||||
assertEquals(effect, 0);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Order(11)
|
||||
public void delete${type}Test() {
|
||||
${type}QueryRequest query = new ${type}QueryRequest();
|
||||
Integer effect = ${typeLower}Service.delete${type}(query);
|
||||
assertEquals(effect, 0);
|
||||
}
|
||||
#if($cacheMeta.enableCache)
|
||||
|
||||
// -------------------- cache --------------------
|
||||
|
||||
@Test
|
||||
@Order(12)
|
||||
public void get${type}ListByCacheTest() {
|
||||
this.create${type}Test();
|
||||
List<${type}VO> list = ${typeLower}Service.get${type}ListByCache();
|
||||
assertEquals(list.size(), 1);
|
||||
}
|
||||
#end
|
||||
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
-- 执行完成后 需要在菜单页面刷新缓存
|
||||
|
||||
-- 父菜单
|
||||
INSERT INTO system_menu
|
||||
(parent_id, name, type, sort, visible, status, cache, component)
|
||||
VALUES
|
||||
(0, '${table.comment}管理', 1, 10, 1, 1, 1, '$vue.moduleEntityFirstLower');
|
||||
|
||||
-- 设置临时父菜单id
|
||||
SELECT @TMP_PARENT_ID:=LAST_INSERT_ID();
|
||||
|
||||
-- 子菜单
|
||||
INSERT INTO system_menu
|
||||
(parent_id, name, type, sort, visible, status, cache, component)
|
||||
VALUES
|
||||
(@TMP_PARENT_ID, '$table.comment', 2, 10, 1, 1, 1, '$vue.moduleEntityFirstLower$vue.featureEntity');
|
||||
|
||||
-- 设置临时子菜单id
|
||||
SELECT @TMP_SUB_ID:=LAST_INSERT_ID();
|
||||
|
||||
-- 功能
|
||||
INSERT INTO system_menu
|
||||
(parent_id, name, permission, type, sort)
|
||||
VALUES
|
||||
(@TMP_SUB_ID, '查询$table.comment', '${package.ModuleName}:${typeHyphen}:query', 3, 10),
|
||||
(@TMP_SUB_ID, '创建$table.comment', '${package.ModuleName}:${typeHyphen}:create', 3, 20),
|
||||
(@TMP_SUB_ID, '修改$table.comment', '${package.ModuleName}:${typeHyphen}:update', 3, 30),
|
||||
(@TMP_SUB_ID, '删除$table.comment', '${package.ModuleName}:${typeHyphen}:delete', 3, 40),
|
||||
(@TMP_SUB_ID, '导出$table.comment', '${package.ModuleName}:${typeHyphen}:export', 3, 50),
|
||||
(@TMP_SUB_ID, '导入$table.comment', '${package.ModuleName}:${typeHyphen}:import', 3, 60);
|
||||
@@ -0,0 +1,142 @@
|
||||
import type { DataGrid, Pagination } from '@/types/global';
|
||||
import type { TableData } from '@arco-design/web-vue/es/table/interface';
|
||||
import axios from 'axios';
|
||||
import qs from 'query-string';
|
||||
|
||||
/**
|
||||
* ${table.comment}创建请求
|
||||
*/
|
||||
export interface ${vue.featureEntity}CreateRequest {
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
#if("$field.propertyType" == "String" || "$field.propertyType" == "Date")
|
||||
${field.propertyName}?: string;
|
||||
#elseif("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
|
||||
${field.propertyName}?: number;
|
||||
#elseif("$field.propertyType" == "Boolean")
|
||||
${field.propertyName}?: boolean;
|
||||
#else
|
||||
${field.propertyName}?: any;
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* ${table.comment}更新请求
|
||||
*/
|
||||
export interface ${vue.featureEntity}UpdateRequest extends ${vue.featureEntity}CreateRequest {
|
||||
id?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* ${table.comment}查询请求
|
||||
*/
|
||||
export interface ${vue.featureEntity}QueryRequest extends Pagination {
|
||||
searchValue?: string;
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$field.propertyType" == "String" || "$field.propertyType" == "Date")
|
||||
${field.propertyName}?: string;
|
||||
#elseif("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
|
||||
${field.propertyName}?: number;
|
||||
#elseif("$field.propertyType" == "Boolean")
|
||||
${field.propertyName}?: boolean;
|
||||
#else
|
||||
${field.propertyName}?: any;
|
||||
#end
|
||||
#end
|
||||
}
|
||||
|
||||
/**
|
||||
* ${table.comment}查询响应
|
||||
*/
|
||||
export interface ${vue.featureEntity}QueryResponse extends TableData {
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$field.propertyType" == "String")
|
||||
${field.propertyName}?: string;
|
||||
#elseif("$field.propertyType" == "Integer" || "$field.propertyType" == "Long" || "$field.propertyType" == "Date")
|
||||
${field.propertyName}?: number;
|
||||
#elseif("$field.propertyType" == "Boolean")
|
||||
${field.propertyName}?: boolean;
|
||||
#else
|
||||
${field.propertyName}?: any;
|
||||
#end
|
||||
#end
|
||||
createTime: number;
|
||||
updateTime: number;
|
||||
creator: string;
|
||||
updater: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.create
|
||||
*/
|
||||
export function create${vue.featureEntity}(request: ${vue.featureEntity}CreateRequest) {
|
||||
return axios.post('/${package.ModuleName}/${typeHyphen}/create', request);
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.updateById
|
||||
*/
|
||||
export function update${vue.featureEntity}(request: ${vue.featureEntity}UpdateRequest) {
|
||||
return axios.put('/${package.ModuleName}/${typeHyphen}/update', request);
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.getById
|
||||
*/
|
||||
export function get${vue.featureEntity}(id: number) {
|
||||
return axios.get<${vue.featureEntity}QueryResponse>('/${package.ModuleName}/${typeHyphen}/get', { params: { id } });
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.getByIdList
|
||||
*/
|
||||
export function batchGet${vue.featureEntity}List(idList: Array<number>) {
|
||||
return axios.get<${vue.featureEntity}QueryResponse[]>('/${package.ModuleName}/${typeHyphen}/batch-get', {
|
||||
params: { idList },
|
||||
paramsSerializer: params => {
|
||||
return qs.stringify(params, { arrayFormat: 'comma' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.queryList
|
||||
*/
|
||||
export function get${vue.featureEntity}List(request: ${vue.featureEntity}QueryRequest) {
|
||||
return axios.post<Array<${vue.featureEntity}QueryResponse>>('/${package.ModuleName}/${typeHyphen}/list', request);
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.queryPage
|
||||
*/
|
||||
export function get${vue.featureEntity}Page(request: ${vue.featureEntity}QueryRequest) {
|
||||
return axios.post<DataGrid<${vue.featureEntity}QueryResponse>>('/${package.ModuleName}/${typeHyphen}/query', request);
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.deleteById
|
||||
*/
|
||||
export function delete${vue.featureEntity}(id: number) {
|
||||
return axios.delete('/${package.ModuleName}/${typeHyphen}/delete', { params: { id } });
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.batchDelete
|
||||
*/
|
||||
export function batchDelete${vue.featureEntity}(idList: Array<number>) {
|
||||
return axios.delete('/${package.ModuleName}/${typeHyphen}/batch-delete', {
|
||||
params: { idList },
|
||||
paramsSerializer: params => {
|
||||
return qs.stringify(params, { arrayFormat: 'comma' });
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* $apiComment.export
|
||||
*/
|
||||
export function export${vue.featureEntity}(request: ${vue.featureEntity}QueryRequest) {
|
||||
return axios.post('/${package.ModuleName}/${typeHyphen}/export', request);
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import type { AppRouteRecordRaw } from '../types';
|
||||
import { DEFAULT_LAYOUT } from '../base';
|
||||
|
||||
const $vue.moduleConst: AppRouteRecordRaw = {
|
||||
name: '$vue.moduleEntityFirstLower',
|
||||
path: '/$vue.module',
|
||||
component: DEFAULT_LAYOUT,
|
||||
children: [
|
||||
{
|
||||
name: '$vue.moduleEntityFirstLower$vue.featureEntity',
|
||||
path: '/$vue.module/$vue.feature',
|
||||
component: () => import('@/views/$vue.module/$vue.feature/index.vue'),
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
export default $vue.moduleConst;
|
||||
@@ -0,0 +1,217 @@
|
||||
<template>
|
||||
<card-list v-model:searchValue="formModel.searchValue"
|
||||
search-input-placeholder="输入xxx"
|
||||
create-card-position="head"
|
||||
:loading="loading"
|
||||
:fieldConfig="fieldConfig"
|
||||
:list="list"
|
||||
:pagination="pagination"
|
||||
:card-layout-cols="cardColLayout"
|
||||
:filter-count="filterCount"
|
||||
:add-permission="['${package.ModuleName}:${typeHyphen}:create']"
|
||||
@add="emits('openAdd')"
|
||||
@reset="reset"
|
||||
@search="fetchCardData"
|
||||
@page-change="fetchCardData">
|
||||
<!-- 标题 -->
|
||||
<template #title="{ record }">
|
||||
{{ record.id }}
|
||||
</template>
|
||||
<!-- 拓展操作 -->
|
||||
<template #extra="{ record }">
|
||||
<a-space>
|
||||
<!-- 更多操作 -->
|
||||
<a-dropdown trigger="hover">
|
||||
<icon-more class="card-extra-icon" />
|
||||
<template #content>
|
||||
<!-- 修改 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
|
||||
@click="emits('openUpdate', record)">
|
||||
<icon-edit />
|
||||
修改
|
||||
</a-doption>
|
||||
<!-- 删除 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
|
||||
class="span-red"
|
||||
@click="deleteRow(record.id)">
|
||||
<icon-delete />
|
||||
删除
|
||||
</a-doption>
|
||||
</template>
|
||||
</a-dropdown>
|
||||
</a-space>
|
||||
</template>
|
||||
<!-- 右键菜单 -->
|
||||
<template #contextMenu="{ record }">
|
||||
<!-- 修改 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:update']"
|
||||
@click="emits('openUpdate', record)">
|
||||
<icon-edit />
|
||||
修改
|
||||
</a-doption>
|
||||
<!-- 删除 -->
|
||||
<a-doption v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
|
||||
class="span-red"
|
||||
@click="deleteRow(record.id)">
|
||||
<icon-delete />
|
||||
删除
|
||||
</a-doption>
|
||||
</template>
|
||||
<!-- 过滤条件 -->
|
||||
<template #filterContent>
|
||||
<a-form :model="formModel"
|
||||
class="modal-form"
|
||||
size="small"
|
||||
ref="formRef"
|
||||
label-align="right"
|
||||
:style="{ width: '320px' }"
|
||||
:label-col-props="{ span: 6 }"
|
||||
:wrapper-col-props="{ span: 18 }"
|
||||
@keyup.enter="() => fetchCardData()">
|
||||
#foreach($field in ${table.fields})
|
||||
<!-- $field.comment -->
|
||||
<a-form-item field="${field.propertyName}" label="${field.comment}">
|
||||
#if(${vue.enums.containsKey(${field.propertyName})})
|
||||
<a-select v-model="formModel.${field.propertyName}"
|
||||
:options="toOptions(${vue.enums.get(${field.propertyName}).className})"
|
||||
placeholder="请选择${field.comment}"
|
||||
allow-clear />
|
||||
#else
|
||||
#if("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
|
||||
<a-input-number v-model="formModel.${field.propertyName}"
|
||||
placeholder="请输入${field.comment}"
|
||||
allow-clear
|
||||
hide-button />
|
||||
#elseif("$field.propertyType" == "Date")
|
||||
<a-date-picker v-model="formModel.${field.propertyName}"
|
||||
style="width: 100%"
|
||||
placeholder="请选择${field.comment}"
|
||||
show-time
|
||||
allow-clear />
|
||||
#else
|
||||
<a-input v-model="formModel.${field.propertyName}" placeholder="请输入${field.comment}" allow-clear />
|
||||
#end
|
||||
#end
|
||||
</a-form-item>
|
||||
#end
|
||||
</a-form>
|
||||
</template>
|
||||
</card-list>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '${vue.module}-${vue.feature}-card-list'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ${vue.featureEntity}QueryRequest, ${vue.featureEntity}QueryResponse } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { usePagination, useColLayout } from '@/types/card';
|
||||
import { computed, reactive, ref, onMounted } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import { objectTruthKeyCount, resetObject } from '@/utils';
|
||||
import fieldConfig from '../types/card.fields';
|
||||
import { delete${vue.featureEntity}, get${vue.featureEntity}Page } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { Message, Modal } from '@arco-design/web-vue';
|
||||
import {} from '../types/const';
|
||||
#if($vue.enums.isEmpty())
|
||||
import {} from '../types/enum.types';
|
||||
#else
|
||||
import { #foreach($entry in ${vue.enums.entrySet()})${entry.value.className}#if($foreach.hasNext), #end#end } from '../types/enum.types';
|
||||
#end
|
||||
import { toOptions, getEnumValue } from '@/utils/enum';
|
||||
|
||||
const emits = defineEmits(['openAdd', 'openUpdate']);
|
||||
|
||||
const list = ref<${vue.featureEntity}QueryResponse[]>([]);
|
||||
|
||||
const cardColLayout = useColLayout();
|
||||
const pagination = usePagination();
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
const formRef = ref();
|
||||
const formModel = reactive<${vue.featureEntity}QueryRequest>({
|
||||
searchValue: undefined,
|
||||
#foreach($field in ${table.fields})
|
||||
${field.propertyName}: undefined,
|
||||
#end
|
||||
});
|
||||
|
||||
// 条件数量
|
||||
const filterCount = computed(() => {
|
||||
return objectTruthKeyCount(formModel, ['searchValue']);
|
||||
});
|
||||
|
||||
// 删除当前行
|
||||
const deleteRow = (id: number) => {
|
||||
Modal.confirm({
|
||||
title: '删除前确认!',
|
||||
titleAlign: 'start',
|
||||
content: '确定要删除这条记录吗?',
|
||||
okText: '删除',
|
||||
onOk: async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// 调用删除接口
|
||||
await delete${vue.featureEntity}(id);
|
||||
Message.success('删除成功');
|
||||
// 重新加载数据
|
||||
fetchCardData();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 添加后回调
|
||||
const addedCallback = () => {
|
||||
fetchCardData();
|
||||
};
|
||||
|
||||
// 更新后回调
|
||||
const updatedCallback = () => {
|
||||
fetchCardData();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
addedCallback, updatedCallback
|
||||
});
|
||||
|
||||
// 重置条件
|
||||
const reset = () => {
|
||||
resetObject(formModel);
|
||||
fetchCardData();
|
||||
};
|
||||
|
||||
// 加载数据
|
||||
const doFetchCardData = async (request: ${vue.featureEntity}QueryRequest) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data } = await get${vue.featureEntity}Page(request);
|
||||
list.value = data.rows;
|
||||
pagination.total = data.total;
|
||||
pagination.current = request.page;
|
||||
pagination.pageSize = request.limit;
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 切换页码
|
||||
const fetchCardData = (page = 1, limit = pagination.pageSize, form = formModel) => {
|
||||
doFetchCardData({ page, limit, ...form });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchCardData();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,157 @@
|
||||
<template>
|
||||
<a-drawer v-model:visible="visible"
|
||||
:title="title"
|
||||
:width="430"
|
||||
:mask-closable="false"
|
||||
:unmount-on-close="true"
|
||||
:ok-button-props="{ disabled: loading }"
|
||||
:cancel-button-props="{ disabled: loading }"
|
||||
:on-before-ok="handlerOk"
|
||||
@cancel="handleClose">
|
||||
<a-spin :loading="loading">
|
||||
<a-form :model="formModel"
|
||||
ref="formRef"
|
||||
label-align="right"
|
||||
:style="{ width: '380px' }"
|
||||
:label-col-props="{ span: 6 }"
|
||||
:wrapper-col-props="{ span: 18 }"
|
||||
:rules="formRules">
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$field.propertyName" != "id")
|
||||
<!-- $field.comment -->
|
||||
<a-form-item field="${field.propertyName}" label="${field.comment}">
|
||||
#if(${vue.enums.containsKey(${field.propertyName})})
|
||||
<a-select v-model="formModel.${field.propertyName}"
|
||||
:options="toOptions(${vue.enums.get(${field.propertyName}).className})"
|
||||
placeholder="请选择${field.comment}"/>
|
||||
#else
|
||||
#if("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
|
||||
<a-input-number v-model="formModel.${field.propertyName}"
|
||||
placeholder="请输入${field.comment}"
|
||||
hide-button />
|
||||
#elseif("$field.propertyType" == "Date")
|
||||
<a-date-picker v-model="formModel.${field.propertyName}"
|
||||
style="width: 100%"
|
||||
placeholder="请选择${field.comment}"
|
||||
show-time />
|
||||
#else
|
||||
<a-input v-model="formModel.${field.propertyName}" placeholder="请输入${field.comment}" allow-clear/>
|
||||
#end
|
||||
#end
|
||||
</a-form-item>
|
||||
#end
|
||||
#end
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-drawer>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '${vue.module}-${vue.feature}-form-drawer'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ${vue.featureEntity}UpdateRequest } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { ref } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import formRules from '../types/form.rules';
|
||||
import { create${vue.featureEntity}, update${vue.featureEntity} } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import {} from '../types/const';
|
||||
#if($vue.enums.isEmpty())
|
||||
import {} from '../types/enum.types';
|
||||
#else
|
||||
import { #foreach($entry in ${vue.enums.entrySet()})${entry.value.className}#if($foreach.hasNext), #end#end } from '../types/enum.types';
|
||||
#end
|
||||
import { toOptions } from '@/utils/enum';
|
||||
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
const title = ref<string>();
|
||||
const isAddHandle = ref<boolean>(true);
|
||||
|
||||
const defaultForm = (): ${vue.featureEntity}UpdateRequest => {
|
||||
return {
|
||||
#foreach($field in ${table.fields})
|
||||
${field.propertyName}: undefined,
|
||||
#end
|
||||
};
|
||||
};
|
||||
|
||||
const formRef = ref<any>();
|
||||
const formModel = ref<${vue.featureEntity}UpdateRequest>({});
|
||||
|
||||
const emits = defineEmits(['added', 'updated']);
|
||||
|
||||
// 打开新增
|
||||
const openAdd = () => {
|
||||
title.value = '添加${table.comment}';
|
||||
isAddHandle.value = true;
|
||||
renderForm({ ...defaultForm() });
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
// 打开修改
|
||||
const openUpdate = (record: any) => {
|
||||
title.value = '修改${table.comment}';
|
||||
isAddHandle.value = false;
|
||||
renderForm({ ...defaultForm(), ...record });
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
// 渲染表单
|
||||
const renderForm = (record: any) => {
|
||||
formModel.value = Object.assign({}, record);
|
||||
};
|
||||
|
||||
defineExpose({ openAdd, openUpdate });
|
||||
|
||||
// 确定
|
||||
const handlerOk = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// 验证参数
|
||||
const error = await formRef.value.validate();
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
if (isAddHandle.value) {
|
||||
// 新增
|
||||
await create${vue.featureEntity}(formModel.value);
|
||||
Message.success('创建成功');
|
||||
emits('added');
|
||||
} else {
|
||||
// 修改
|
||||
await update${vue.featureEntity}(formModel.value);
|
||||
Message.success('修改成功');
|
||||
emits('updated');
|
||||
}
|
||||
// 清空
|
||||
handlerClear();
|
||||
} catch (e) {
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
handlerClear();
|
||||
};
|
||||
|
||||
// 清空
|
||||
const handlerClear = () => {
|
||||
setLoading(false);
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,161 @@
|
||||
<template>
|
||||
<a-modal v-model:visible="visible"
|
||||
body-class="modal-form"
|
||||
title-align="start"
|
||||
:title="title"
|
||||
:top="80"
|
||||
:align-center="false"
|
||||
:draggable="true"
|
||||
:mask-closable="false"
|
||||
:unmount-on-close="true"
|
||||
:ok-button-props="{ disabled: loading }"
|
||||
:cancel-button-props="{ disabled: loading }"
|
||||
:on-before-ok="handlerOk"
|
||||
@close="handleClose">
|
||||
<a-spin :loading="loading">
|
||||
<a-form :model="formModel"
|
||||
ref="formRef"
|
||||
label-align="right"
|
||||
:style="{ width: '460px' }"
|
||||
:label-col-props="{ span: 6 }"
|
||||
:wrapper-col-props="{ span: 18 }"
|
||||
:rules="formRules">
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$field.propertyName" != "id")
|
||||
<!-- $field.comment -->
|
||||
<a-form-item field="${field.propertyName}" label="${field.comment}">
|
||||
#if(${vue.enums.containsKey(${field.propertyName})})
|
||||
<a-select v-model="formModel.${field.propertyName}"
|
||||
:options="toOptions(${vue.enums.get(${field.propertyName}).className})"
|
||||
placeholder="请选择${field.comment}" />
|
||||
#else
|
||||
#if("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
|
||||
<a-input-number v-model="formModel.${field.propertyName}"
|
||||
placeholder="请输入${field.comment}"
|
||||
hide-button />
|
||||
#elseif("$field.propertyType" == "Date")
|
||||
<a-date-picker v-model="formModel.${field.propertyName}"
|
||||
style="width: 100%"
|
||||
placeholder="请选择${field.comment}"
|
||||
show-time />
|
||||
#else
|
||||
<a-input v-model="formModel.${field.propertyName}" placeholder="请输入${field.comment}" allow-clear />
|
||||
#end
|
||||
#end
|
||||
</a-form-item>
|
||||
#end
|
||||
#end
|
||||
</a-form>
|
||||
</a-spin>
|
||||
</a-modal>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '${vue.module}-${vue.feature}-form-modal'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ${vue.featureEntity}UpdateRequest } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { ref } from 'vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import useVisible from '@/hooks/visible';
|
||||
import formRules from '../types/form.rules';
|
||||
import { create${vue.featureEntity}, update${vue.featureEntity} } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import {} from '../types/const';
|
||||
#if($vue.enums.isEmpty())
|
||||
import {} from '../types/enum.types';
|
||||
#else
|
||||
import { #foreach($entry in ${vue.enums.entrySet()})${entry.value.className}#if($foreach.hasNext), #end#end } from '../types/enum.types';
|
||||
#end
|
||||
import { toOptions } from '@/utils/enum';
|
||||
|
||||
const { visible, setVisible } = useVisible();
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
const title = ref<string>();
|
||||
const isAddHandle = ref<boolean>(true);
|
||||
|
||||
const defaultForm = (): ${vue.featureEntity}UpdateRequest => {
|
||||
return {
|
||||
#foreach($field in ${table.fields})
|
||||
${field.propertyName}: undefined,
|
||||
#end
|
||||
};
|
||||
};
|
||||
|
||||
const formRef = ref<any>();
|
||||
const formModel = ref<${vue.featureEntity}UpdateRequest>({});
|
||||
|
||||
const emits = defineEmits(['added', 'updated']);
|
||||
|
||||
// 打开新增
|
||||
const openAdd = () => {
|
||||
title.value = '添加${table.comment}';
|
||||
isAddHandle.value = true;
|
||||
renderForm({ ...defaultForm() });
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
// 打开修改
|
||||
const openUpdate = (record: any) => {
|
||||
title.value = '修改${table.comment}';
|
||||
isAddHandle.value = false;
|
||||
renderForm({ ...defaultForm(), ...record });
|
||||
setVisible(true);
|
||||
};
|
||||
|
||||
// 渲染表单
|
||||
const renderForm = (record: any) => {
|
||||
formModel.value = Object.assign({}, record);
|
||||
};
|
||||
|
||||
defineExpose({ openAdd, openUpdate });
|
||||
|
||||
// 确定
|
||||
const handlerOk = async () => {
|
||||
setLoading(true);
|
||||
try {
|
||||
// 验证参数
|
||||
const error = await formRef.value.validate();
|
||||
if (error) {
|
||||
return false;
|
||||
}
|
||||
if (isAddHandle.value) {
|
||||
// 新增
|
||||
await create${vue.featureEntity}(formModel.value);
|
||||
Message.success('创建成功');
|
||||
emits('added');
|
||||
} else {
|
||||
// 修改
|
||||
await update${vue.featureEntity}(formModel.value);
|
||||
Message.success('修改成功');
|
||||
emits('updated');
|
||||
}
|
||||
// 清空
|
||||
handlerClear();
|
||||
} catch (e) {
|
||||
return false;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 关闭
|
||||
const handleClose = () => {
|
||||
handlerClear();
|
||||
};
|
||||
|
||||
// 清空
|
||||
const handlerClear = () => {
|
||||
setLoading(false);
|
||||
setVisible(false);
|
||||
};
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,256 @@
|
||||
<template>
|
||||
<!-- 搜索 -->
|
||||
<a-card class="general-card table-search-card">
|
||||
<a-query-header :model="formModel"
|
||||
label-align="left"
|
||||
@submit="fetchTableData"
|
||||
@reset="fetchTableData"
|
||||
@keyup.enter="() => fetchTableData()">
|
||||
#foreach($field in ${table.fields})
|
||||
<!-- $field.comment -->
|
||||
<a-form-item field="${field.propertyName}" label="${field.comment}" label-col-flex="50px">
|
||||
#if(${vue.enums.containsKey(${field.propertyName})})
|
||||
<a-select v-model="formModel.${field.propertyName}"
|
||||
:options="toOptions(${vue.enums.get(${field.propertyName}).className})"
|
||||
placeholder="请选择${field.comment}"
|
||||
allow-clear />
|
||||
#else
|
||||
#if("$field.propertyType" == "Integer" || "$field.propertyType" == "Long")
|
||||
<a-input-number v-model="formModel.${field.propertyName}"
|
||||
placeholder="请输入${field.comment}"
|
||||
allow-clear
|
||||
hide-button />
|
||||
#elseif("$field.propertyType" == "Date")
|
||||
<a-date-picker v-model="formModel.${field.propertyName}"
|
||||
style="width: 100%"
|
||||
placeholder="请选择${field.comment}"
|
||||
show-time
|
||||
allow-clear />
|
||||
#else
|
||||
<a-input v-model="formModel.${field.propertyName}" placeholder="请输入${field.comment}" allow-clear />
|
||||
#end
|
||||
#end
|
||||
</a-form-item>
|
||||
#end
|
||||
</a-query-header>
|
||||
</a-card>
|
||||
<!-- 表格 -->
|
||||
<a-card class="general-card table-card">
|
||||
<template #title>
|
||||
<!-- 左侧操作 -->
|
||||
<div class="table-left-bar-handle">
|
||||
<!-- 标题 -->
|
||||
<div class="table-title">
|
||||
${table.comment}列表
|
||||
</div>
|
||||
</div>
|
||||
<!-- 右侧操作 -->
|
||||
<div class="table-right-bar-handle">
|
||||
<a-space>
|
||||
<!-- 新增 -->
|
||||
<a-button type="primary"
|
||||
v-permission="['${package.ModuleName}:${typeHyphen}:create']"
|
||||
@click="emits('openAdd')">
|
||||
新增
|
||||
<template #icon>
|
||||
<icon-plus />
|
||||
</template>
|
||||
</a-button>
|
||||
#if($vue.enableRowSelection)
|
||||
<!-- 删除 -->
|
||||
<a-popconfirm position="br"
|
||||
type="warning"
|
||||
:content="`确认删除选中的${selectedKeys.length}条记录吗?`"
|
||||
@ok="deleteSelectRows">
|
||||
<a-button v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
|
||||
type="secondary"
|
||||
status="danger"
|
||||
:disabled="selectedKeys.length === 0">
|
||||
删除
|
||||
<template #icon>
|
||||
<icon-delete />
|
||||
</template>
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
#end
|
||||
</a-space>
|
||||
</div>
|
||||
</template>
|
||||
<!-- table -->
|
||||
<a-table row-key="id"
|
||||
class="table-wrapper-8"
|
||||
ref="tableRef"
|
||||
label-align="left"
|
||||
:loading="loading"
|
||||
:columns="columns"
|
||||
#if($vue.enableRowSelection)
|
||||
v-model:selected-keys="selectedKeys"
|
||||
:row-selection="rowSelection"
|
||||
#end
|
||||
:data="tableRenderData"
|
||||
:pagination="pagination"
|
||||
@page-change="(page) => fetchTableData(page, pagination.pageSize)"
|
||||
@page-size-change="(size) => fetchTableData(1, size)"
|
||||
:bordered="false">
|
||||
#foreach($field in ${table.fields})
|
||||
#if(${vue.enums.containsKey(${field.propertyName})})
|
||||
<!-- $field.comment -->
|
||||
<template #${field.propertyName}="{ record }">
|
||||
{{ getEnumValue(record.${field.propertyName}, ${vue.enums.get(${field.propertyName}).className}) }}
|
||||
</template>
|
||||
#end
|
||||
#end
|
||||
<!-- 操作 -->
|
||||
<template #handle="{ record }">
|
||||
<div class="table-handle-wrapper">
|
||||
<!-- 修改 -->
|
||||
<a-button type="text"
|
||||
size="mini"
|
||||
v-permission="['${package.ModuleName}:${typeHyphen}:update']"
|
||||
@click="emits('openUpdate', record)">
|
||||
修改
|
||||
</a-button>
|
||||
<!-- 删除 -->
|
||||
<a-popconfirm content="确认删除这条记录吗?"
|
||||
position="left"
|
||||
type="warning"
|
||||
@ok="deleteRow(record)">
|
||||
<a-button v-permission="['${package.ModuleName}:${typeHyphen}:delete']"
|
||||
type="text"
|
||||
size="mini"
|
||||
status="danger">
|
||||
删除
|
||||
</a-button>
|
||||
</a-popconfirm>
|
||||
</div>
|
||||
</template>
|
||||
</a-table>
|
||||
</a-card>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '${vue.module}-${vue.feature}-table'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { ${vue.featureEntity}QueryRequest, ${vue.featureEntity}QueryResponse } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { reactive, ref, onMounted } from 'vue';
|
||||
import { batchDelete${vue.featureEntity}, delete${vue.featureEntity}, get${vue.featureEntity}Page } from '@/api/${vue.module}/${vue.feature}';
|
||||
import { Message } from '@arco-design/web-vue';
|
||||
import useLoading from '@/hooks/loading';
|
||||
import columns from '../types/table.columns';
|
||||
#if($vue.enableRowSelection)
|
||||
import { usePagination, useRowSelection } from '@/types/table';
|
||||
#else
|
||||
import { usePagination } from '@/types/table';
|
||||
#end
|
||||
import {} from '../types/const';
|
||||
#if($vue.enums.isEmpty())
|
||||
import {} from '../types/enum.types';
|
||||
#else
|
||||
import { #foreach($entry in ${vue.enums.entrySet()})${entry.value.className}#if($foreach.hasNext), #end#end } from '../types/enum.types';
|
||||
#end
|
||||
import { toOptions, getEnumValue } from '@/utils/enum';
|
||||
|
||||
const emits = defineEmits(['openAdd', 'openUpdate']);
|
||||
|
||||
#if($vue.enableRowSelection)
|
||||
const selectedKeys = ref<number[]>([]);
|
||||
#end
|
||||
const tableRenderData = ref<${vue.featureEntity}QueryResponse[]>([]);
|
||||
|
||||
const pagination = usePagination();
|
||||
#if($vue.enableRowSelection)
|
||||
const rowSelection = useRowSelection();
|
||||
#end
|
||||
const { loading, setLoading } = useLoading();
|
||||
|
||||
const formModel = reactive<${vue.featureEntity}QueryRequest>({
|
||||
#foreach($field in ${table.fields})
|
||||
${field.propertyName}: undefined,
|
||||
#end
|
||||
});
|
||||
|
||||
#if($vue.enableRowSelection)
|
||||
// 删除选中行
|
||||
const deleteSelectRows = async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// 调用删除接口
|
||||
await batchDelete${vue.featureEntity}(selectedKeys.value);
|
||||
Message.success(`成功删除${selectedKeys.value.length}条数据`);
|
||||
selectedKeys.value = [];
|
||||
// 重新加载数据
|
||||
fetchTableData();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
#end
|
||||
// 删除当前行
|
||||
const deleteRow = async ({ id }: {
|
||||
id: number
|
||||
}) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
// 调用删除接口
|
||||
await delete${vue.featureEntity}(id);
|
||||
Message.success('删除成功');
|
||||
// 重新加载数据
|
||||
fetchTableData();
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 添加后回调
|
||||
const addedCallback = () => {
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
// 更新后回调
|
||||
const updatedCallback = () => {
|
||||
fetchTableData();
|
||||
};
|
||||
|
||||
defineExpose({
|
||||
addedCallback, updatedCallback
|
||||
});
|
||||
|
||||
// 加载数据
|
||||
const doFetchTableData = async (request: ${vue.featureEntity}QueryRequest) => {
|
||||
try {
|
||||
setLoading(true);
|
||||
const { data } = await get${vue.featureEntity}Page(request);
|
||||
tableRenderData.value = data.rows;
|
||||
pagination.total = data.total;
|
||||
pagination.current = request.page;
|
||||
pagination.pageSize = request.limit;
|
||||
#if($vue.enableRowSelection)
|
||||
selectedKeys.value = [];
|
||||
#end
|
||||
} catch (e) {
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
// 切换页码
|
||||
const fetchTableData = (page = 1, limit = pagination.pageSize, form = formModel) => {
|
||||
doFetchTableData({ page, limit, ...form });
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
fetchTableData();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,109 @@
|
||||
<template>
|
||||
<div class="layout-container" v-if="render">
|
||||
#if($vue.enableCardView)
|
||||
<!-- 列表-表格 -->
|
||||
<${vue.feature}-table v-if="renderTable"
|
||||
ref="table"
|
||||
@openAdd="() =>#if($vue.enableDrawerForm) drawer#else modal#end.openAdd()"
|
||||
@openUpdate="(e) =>#if($vue.enableDrawerForm) drawer#else modal#end.openUpdate(e)" />
|
||||
<!-- 列表-卡片 -->
|
||||
<${vue.feature}-card-list v-else
|
||||
ref="card"
|
||||
@openAdd="() =>#if($vue.enableDrawerForm) drawer#else modal#end.openAdd()"
|
||||
@openUpdate="(e) =>#if($vue.enableDrawerForm) drawer#else modal#end.openUpdate(e)" />
|
||||
#else
|
||||
<!-- 列表-表格 -->
|
||||
<${vue.feature}-table ref="table"
|
||||
@openAdd="() =>#if($vue.enableDrawerForm) drawer#else modal#end.openAdd()"
|
||||
@openUpdate="(e) =>#if($vue.enableDrawerForm) drawer#else modal#end.openUpdate(e)" />
|
||||
#end
|
||||
#if($vue.enableDrawerForm)
|
||||
<!-- 添加修改模态框 -->
|
||||
<${vue.feature}-form-drawer ref="drawer"
|
||||
@added="modalAddCallback"
|
||||
@updated="modalUpdateCallback" />
|
||||
#else
|
||||
<!-- 添加修改模态框 -->
|
||||
<${vue.feature}-form-modal ref="modal"
|
||||
@added="modalAddCallback"
|
||||
@updated="modalUpdateCallback" />
|
||||
#end
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: '${vue.moduleEntityFirstLower}${vue.featureEntity}'
|
||||
};
|
||||
</script>
|
||||
|
||||
<script lang="ts" setup>
|
||||
#if($vue.enableCardView)
|
||||
import ${vue.featureEntity}CardList from './components/${vue.feature}-card-list.vue';
|
||||
#end
|
||||
import ${vue.featureEntity}Table from './components/${vue.feature}-table.vue';
|
||||
#if($vue.enableDrawerForm)
|
||||
import ${vue.featureEntity}FormDrawer from './components/${vue.feature}-form-drawer.vue';
|
||||
#else
|
||||
import ${vue.featureEntity}FormModal from './components/${vue.feature}-form-modal.vue';
|
||||
#end
|
||||
|
||||
#if($vue.enableCardView)
|
||||
import { computed, ref, onBeforeMount } from 'vue';
|
||||
import { useAppStore } from '@/store';
|
||||
#else
|
||||
import { ref } from 'vue';
|
||||
#end
|
||||
|
||||
const render = ref(false);
|
||||
const table = ref();
|
||||
#if($vue.enableCardView)
|
||||
const card = ref();
|
||||
#end
|
||||
#if($vue.enableDrawerForm)
|
||||
const drawer = ref();
|
||||
#else
|
||||
const modal = ref();
|
||||
#end
|
||||
#if($vue.enableCardView)
|
||||
const appStore = useAppStore();
|
||||
|
||||
// FIXME 这里需要修改一下字段名称
|
||||
const renderTable = computed(() => appStore.${vue.featureEntityFirstLower}View === 'table');
|
||||
#end
|
||||
|
||||
// 添加回调
|
||||
const modalAddCallback = () => {
|
||||
#if($vue.enableCardView)
|
||||
if (renderTable.value) {
|
||||
table.value.addedCallback();
|
||||
} else {
|
||||
card.value.addedCallback();
|
||||
}
|
||||
#else
|
||||
table.value.addedCallback();
|
||||
#end
|
||||
};
|
||||
|
||||
// 修改回调
|
||||
const modalUpdateCallback = () => {
|
||||
#if($vue.enableCardView)
|
||||
if (renderTable.value) {
|
||||
table.value.updatedCallback();
|
||||
} else {
|
||||
card.value.updatedCallback();
|
||||
}
|
||||
#else
|
||||
table.value.updatedCallback();
|
||||
#end
|
||||
};
|
||||
|
||||
onBeforeMount(async () => {
|
||||
render.value = true;
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { CardField, CardFieldConfig } from '@/types/card';
|
||||
import { dateFormat } from '@/utils';
|
||||
|
||||
const fieldConfig = {
|
||||
rowGap: '12px',
|
||||
labelSpan: 8,
|
||||
fields: [
|
||||
{
|
||||
label: 'id',
|
||||
dataIndex: 'id',
|
||||
slotName: 'id',
|
||||
}, #foreach($field in ${table.fields})#if("$!field.propertyName" != "id"){
|
||||
label: '${field.comment}',
|
||||
dataIndex: '${field.propertyName}',
|
||||
slotName: '${field.propertyName}',
|
||||
#if(${field.propertyType} == 'String')
|
||||
ellipsis: true,
|
||||
#elseif(${field.propertyType} == 'Date')
|
||||
render: ({ record }) => {
|
||||
return record.${field.propertyName} && dateFormat(new Date(record.${field.propertyName}));
|
||||
},
|
||||
#end
|
||||
}, #end#end{
|
||||
label: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
slotName: 'createTime',
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.createTime));
|
||||
},
|
||||
}, {
|
||||
label: '修改时间',
|
||||
dataIndex: 'updateTime',
|
||||
slotName: 'updateTime',
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.updateTime));
|
||||
},
|
||||
}, {
|
||||
label: '创建人',
|
||||
dataIndex: 'creator',
|
||||
slotName: 'creator',
|
||||
}, {
|
||||
label: '修改人',
|
||||
dataIndex: 'updater',
|
||||
slotName: 'updater',
|
||||
}
|
||||
] as CardField[]
|
||||
} as CardFieldConfig;
|
||||
|
||||
export default fieldConfig;
|
||||
@@ -0,0 +1,15 @@
|
||||
#foreach($enumEntity in ${vue.enums.entrySet()})
|
||||
/**
|
||||
* $!{enumEntity.value.comment}
|
||||
*/
|
||||
export const $enumEntity.value.className = {
|
||||
#foreach($enumEntityItem in $enumEntity.value.info.entrySet())
|
||||
$enumEntityItem.key: {
|
||||
#foreach($enumEntityItemFields in $enumEntityItem.value.entrySet())
|
||||
$enumEntityItemFields.key: '$!enumEntityItemFields.value',
|
||||
#end
|
||||
},
|
||||
#end
|
||||
}
|
||||
|
||||
#end
|
||||
@@ -0,0 +1,27 @@
|
||||
import type { FieldRule } from '@arco-design/web-vue';
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
#if(${field.propertyType} == 'String' && "$field.metaInfo.jdbcType" != "LONGVARCHAR")
|
||||
export const ${field.propertyName} = [{
|
||||
required: true,
|
||||
message: '请输入${field.comment}'
|
||||
}, {
|
||||
maxLength: $field.metaInfo.length,
|
||||
message: '${field.comment}长度不能大于$field.metaInfo.length位'
|
||||
}] as FieldRule[];
|
||||
#else
|
||||
export const ${field.propertyName} = [{
|
||||
required: true,
|
||||
message: '请输入${field.comment}'
|
||||
}] as FieldRule[];
|
||||
#end
|
||||
#end
|
||||
|
||||
#end
|
||||
export default {
|
||||
#foreach($field in ${table.fields})
|
||||
#if("$!field.propertyName" != "id")
|
||||
${field.propertyName},
|
||||
#end
|
||||
#end
|
||||
} as Record<string, FieldRule | FieldRule[]>;
|
||||
@@ -0,0 +1,61 @@
|
||||
import type { TableColumnData } from '@arco-design/web-vue/es/table/interface';
|
||||
import { dateFormat } from '@/utils';
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'id',
|
||||
dataIndex: 'id',
|
||||
slotName: 'id',
|
||||
width: 70,
|
||||
align: 'left',
|
||||
fixed: 'left',
|
||||
}, #foreach($field in ${table.fields})#if("$!field.propertyName" != "id"){
|
||||
title: '${field.comment}',
|
||||
dataIndex: '${field.propertyName}',
|
||||
slotName: '${field.propertyName}',
|
||||
align: 'left',
|
||||
#if(${field.propertyType} == 'String')
|
||||
ellipsis: true,
|
||||
tooltip: true,
|
||||
#elseif(${field.propertyType} == 'Date')
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return record.${field.propertyName} && dateFormat(new Date(record.${field.propertyName}));
|
||||
},
|
||||
#end
|
||||
}, #end#end{
|
||||
title: '创建时间',
|
||||
dataIndex: 'createTime',
|
||||
slotName: 'createTime',
|
||||
align: 'center',
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.createTime));
|
||||
},
|
||||
}, {
|
||||
title: '修改时间',
|
||||
dataIndex: 'updateTime',
|
||||
slotName: 'updateTime',
|
||||
align: 'center',
|
||||
width: 180,
|
||||
render: ({ record }) => {
|
||||
return dateFormat(new Date(record.updateTime));
|
||||
},
|
||||
}, {
|
||||
title: '创建人',
|
||||
dataIndex: 'creator',
|
||||
slotName: 'creator',
|
||||
}, {
|
||||
title: '修改人',
|
||||
dataIndex: 'updater',
|
||||
slotName: 'updater',
|
||||
}, {
|
||||
title: '操作',
|
||||
slotName: 'handle',
|
||||
width: 130,
|
||||
align: 'center',
|
||||
fixed: 'right',
|
||||
},
|
||||
] as TableColumnData[];
|
||||
|
||||
export default columns;
|
||||
Reference in New Issue
Block a user