代码生成,支持配置前端 UI 类型
This commit is contained in:
parent
c5b6a2a53d
commit
ca9656a40f
@ -37,7 +37,7 @@ public class CodegenUpdateReqVO {
|
|||||||
@Schema(description = "编号", required = true, example = "1")
|
@Schema(description = "编号", required = true, example = "1")
|
||||||
private Long id;
|
private Long id;
|
||||||
|
|
||||||
@AssertTrue(message = "上级菜单不能为空")
|
@AssertTrue(message = "上级菜单不能为空,请前往 [修改生成配置 -> 生成信息] 界面,设置“上级菜单”字段")
|
||||||
public boolean isParentMenuIdValid() {
|
public boolean isParentMenuIdValid() {
|
||||||
// 生成场景为管理后台时,必须设置上级菜单,不然生成的菜单 SQL 是无父级菜单的
|
// 生成场景为管理后台时,必须设置上级菜单,不然生成的菜单 SQL 是无父级菜单的
|
||||||
return ObjectUtil.notEqual(getScene(), CodegenSceneEnum.ADMIN.getScene())
|
return ObjectUtil.notEqual(getScene(), CodegenSceneEnum.ADMIN.getScene())
|
||||||
|
@ -51,6 +51,10 @@ public class CodegenTableBaseVO {
|
|||||||
@NotNull(message = "模板类型不能为空")
|
@NotNull(message = "模板类型不能为空")
|
||||||
private Integer templateType;
|
private Integer templateType;
|
||||||
|
|
||||||
|
@Schema(description = "前端类型,参见 CodegenFrontTypeEnum 枚举", required = true, example = "20")
|
||||||
|
@NotNull(message = "前端类型不能为空")
|
||||||
|
private Integer frontType;
|
||||||
|
|
||||||
@Schema(description = "父菜单编号", example = "1024")
|
@Schema(description = "父菜单编号", example = "1024")
|
||||||
private Long parentMenuId;
|
private Long parentMenuId;
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package cn.iocoder.yudao.module.infra.dal.dataobject.codegen;
|
|||||||
|
|
||||||
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.db.DataSourceConfigDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenTemplateTypeEnum;
|
||||||
import com.baomidou.mybatisplus.annotation.IdType;
|
import com.baomidou.mybatisplus.annotation.IdType;
|
||||||
@ -100,6 +101,12 @@ public class CodegenTableDO extends BaseDO {
|
|||||||
* 枚举 {@link CodegenTemplateTypeEnum}
|
* 枚举 {@link CodegenTemplateTypeEnum}
|
||||||
*/
|
*/
|
||||||
private Integer templateType;
|
private Integer templateType;
|
||||||
|
/**
|
||||||
|
* 代码生成的前端类型
|
||||||
|
*
|
||||||
|
* 枚举 {@link CodegenFrontTypeEnum}
|
||||||
|
*/
|
||||||
|
private Integer frontType;
|
||||||
|
|
||||||
// ========== 菜单相关字段 ==========
|
// ========== 菜单相关字段 ==========
|
||||||
|
|
||||||
|
@ -0,0 +1,25 @@
|
|||||||
|
package cn.iocoder.yudao.module.infra.enums.codegen;
|
||||||
|
|
||||||
|
import lombok.AllArgsConstructor;
|
||||||
|
import lombok.Getter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成的前端类型枚举
|
||||||
|
*
|
||||||
|
* @author 芋道源码
|
||||||
|
*/
|
||||||
|
@AllArgsConstructor
|
||||||
|
@Getter
|
||||||
|
public enum CodegenFrontTypeEnum {
|
||||||
|
|
||||||
|
VUE2(10), // Vue2 Element UI 标准模版
|
||||||
|
VUE3(20), // Vue3 Element Plus 标准模版
|
||||||
|
VUE3_SCHEMA(21), // Vue3 Element Plus Schema 模版
|
||||||
|
;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 类型
|
||||||
|
*/
|
||||||
|
private final Integer type;
|
||||||
|
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package cn.iocoder.yudao.module.infra.framework.codegen.config;
|
package cn.iocoder.yudao.module.infra.framework.codegen.config;
|
||||||
|
|
||||||
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||||
import lombok.Data;
|
import lombok.Data;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
@ -25,4 +26,12 @@ public class CodegenProperties {
|
|||||||
@NotEmpty(message = "数据库不能为空")
|
@NotEmpty(message = "数据库不能为空")
|
||||||
private Collection<String> dbSchemas;
|
private Collection<String> dbSchemas;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 代码生成的前端类型(默认)
|
||||||
|
*
|
||||||
|
* 枚举 {@link CodegenFrontTypeEnum#getType()}
|
||||||
|
*/
|
||||||
|
@NotNull(message = "代码生成的前端类型不能为空")
|
||||||
|
private Integer frontType;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,7 @@ import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
|||||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenColumnMapper;
|
||||||
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
|
import cn.iocoder.yudao.module.infra.dal.mysql.codegen.CodegenTableMapper;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||||
|
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
|
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenBuilder;
|
||||||
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
|
import cn.iocoder.yudao.module.infra.service.codegen.inner.CodegenEngine;
|
||||||
import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
|
import cn.iocoder.yudao.module.infra.service.db.DatabaseTableService;
|
||||||
@ -58,6 +59,9 @@ public class CodegenServiceImpl implements CodegenService {
|
|||||||
@Resource
|
@Resource
|
||||||
private CodegenEngine codegenEngine;
|
private CodegenEngine codegenEngine;
|
||||||
|
|
||||||
|
@Resource
|
||||||
|
private CodegenProperties codegenProperties;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@Transactional(rollbackFor = Exception.class)
|
@Transactional(rollbackFor = Exception.class)
|
||||||
public List<Long> createCodegenList(Long userId, CodegenCreateListReqVO reqVO) {
|
public List<Long> createCodegenList(Long userId, CodegenCreateListReqVO reqVO) {
|
||||||
@ -87,6 +91,7 @@ public class CodegenServiceImpl implements CodegenService {
|
|||||||
CodegenTableDO table = codegenBuilder.buildTable(tableInfo);
|
CodegenTableDO table = codegenBuilder.buildTable(tableInfo);
|
||||||
table.setDataSourceConfigId(dataSourceConfigId);
|
table.setDataSourceConfigId(dataSourceConfigId);
|
||||||
table.setScene(CodegenSceneEnum.ADMIN.getScene()); // 默认配置下,使用管理后台的模板
|
table.setScene(CodegenSceneEnum.ADMIN.getScene()); // 默认配置下,使用管理后台的模板
|
||||||
|
table.setFrontType(codegenProperties.getFrontType());
|
||||||
table.setAuthor(userApi.getUser(userId).getCheckedData().getNickname());
|
table.setAuthor(userApi.getUser(userId).getCheckedData().getNickname());
|
||||||
codegenTableMapper.insert(table);
|
codegenTableMapper.insert(table);
|
||||||
|
|
||||||
|
@ -23,9 +23,12 @@ import cn.iocoder.yudao.framework.operatelog.core.annotations.OperateLog;
|
|||||||
import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
|
import cn.iocoder.yudao.framework.operatelog.core.enums.OperateTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenColumnDO;
|
||||||
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
import cn.iocoder.yudao.module.infra.dal.dataobject.codegen.CodegenTableDO;
|
||||||
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenFrontTypeEnum;
|
||||||
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
import cn.iocoder.yudao.module.infra.enums.codegen.CodegenSceneEnum;
|
||||||
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
import cn.iocoder.yudao.module.infra.framework.codegen.config.CodegenProperties;
|
||||||
|
import com.google.common.collect.ImmutableTable;
|
||||||
import com.google.common.collect.Maps;
|
import com.google.common.collect.Maps;
|
||||||
|
import com.google.common.collect.Table;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
@ -50,11 +53,12 @@ import static cn.hutool.core.text.CharSequenceUtil.*;
|
|||||||
public class CodegenEngine {
|
public class CodegenEngine {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 模板配置
|
* 后端的模板配置
|
||||||
|
*
|
||||||
* key:模板在 resources 的地址
|
* key:模板在 resources 的地址
|
||||||
* value:生成的路径
|
* value:生成的路径
|
||||||
*/
|
*/
|
||||||
private static final Map<String, String> TEMPLATES = MapUtil.<String, String>builder(new LinkedHashMap<>()) // 有序
|
private static final Map<String, String> SERVER_TEMPLATES = MapUtil.<String, String>builder(new LinkedHashMap<>()) // 有序
|
||||||
// Java module-biz Main
|
// Java module-biz Main
|
||||||
.put(javaTemplatePath("controller/vo/baseVO"), javaModuleImplVOFilePath("BaseVO"))
|
.put(javaTemplatePath("controller/vo/baseVO"), javaModuleImplVOFilePath("BaseVO"))
|
||||||
.put(javaTemplatePath("controller/vo/createReqVO"), javaModuleImplVOFilePath("CreateReqVO"))
|
.put(javaTemplatePath("controller/vo/createReqVO"), javaModuleImplVOFilePath("CreateReqVO"))
|
||||||
@ -80,25 +84,40 @@ public class CodegenEngine {
|
|||||||
javaModuleImplTestFilePath("service/${table.businessName}/${table.className}ServiceImplTest"))
|
javaModuleImplTestFilePath("service/${table.businessName}/${table.className}ServiceImplTest"))
|
||||||
// Java module-api Main
|
// Java module-api Main
|
||||||
.put(javaTemplatePath("enums/errorcode"), javaModuleApiMainFilePath("enums/ErrorCodeConstants_手动操作"))
|
.put(javaTemplatePath("enums/errorcode"), javaModuleApiMainFilePath("enums/ErrorCodeConstants_手动操作"))
|
||||||
// Vue2
|
|
||||||
.put(vueTemplatePath("views/index.vue"),
|
|
||||||
vueFilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
|
|
||||||
.put(vueTemplatePath("api/api.js"),
|
|
||||||
vueFilePath("api/${table.moduleName}/${classNameVar}.js"))
|
|
||||||
// Vue3
|
|
||||||
.put(vue3TemplatePath("views/index.vue"),
|
|
||||||
vue3FilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
|
|
||||||
.put(vue3TemplatePath("views/data.ts"),
|
|
||||||
vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts"))
|
|
||||||
.put(vue3TemplatePath("api/api.ts"),
|
|
||||||
vue3FilePath("api/${table.moduleName}/${classNameVar}/index.ts"))
|
|
||||||
.put(vue3TemplatePath("api/types.ts"),
|
|
||||||
vue3FilePath("api/${table.moduleName}/${classNameVar}/types.ts"))
|
|
||||||
// SQL
|
// SQL
|
||||||
.put("codegen/sql/sql.vm", "sql/sql.sql")
|
.put("codegen/sql/sql.vm", "sql/sql.sql")
|
||||||
.put("codegen/sql/h2.vm", "sql/h2.sql")
|
.put("codegen/sql/h2.vm", "sql/h2.sql")
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 后端的配置模版
|
||||||
|
*
|
||||||
|
* key1:UI 模版的类型 {@link CodegenFrontTypeEnum#getType()}
|
||||||
|
* key2:模板在 resources 的地址
|
||||||
|
* value:生成的路径
|
||||||
|
*/
|
||||||
|
private static final Table<Integer, String, String> FRONT_TEMPLATES = ImmutableTable.<Integer, String, String>builder()
|
||||||
|
// Vue2 标准模版
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("views/index.vue"),
|
||||||
|
vueFilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE2.getType(), vueTemplatePath("api/api.js"),
|
||||||
|
vueFilePath("api/${table.moduleName}/${classNameVar}.js"))
|
||||||
|
// Vue3 标准模版
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/index.vue"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("views/form.vue"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${classNameVar}/${simpleClassName}Form.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3.getType(), vue3TemplatePath("api/api.ts"),
|
||||||
|
vue3FilePath("api/${table.moduleName}/${classNameVar}/index.ts"))
|
||||||
|
// Vue3 Schema 模版
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/data.ts"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${classNameVar}/${classNameVar}.data.ts"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/index.vue"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${classNameVar}/index.vue"))
|
||||||
|
.put(CodegenFrontTypeEnum.VUE3_SCHEMA.getType(), vue3SchemaTemplatePath("views/form.vue"),
|
||||||
|
vue3FilePath("views/${table.moduleName}/${classNameVar}/${simpleClassName}Form.vue"))
|
||||||
|
.build();
|
||||||
|
|
||||||
@Resource
|
@Resource
|
||||||
private CodegenProperties codegenProperties;
|
private CodegenProperties codegenProperties;
|
||||||
|
|
||||||
@ -167,20 +186,32 @@ public class CodegenEngine {
|
|||||||
bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
|
bindingMap.put("permissionPrefix", table.getModuleName() + ":" + simpleClassNameStrikeCase);
|
||||||
|
|
||||||
// 执行生成
|
// 执行生成
|
||||||
final Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(TEMPLATES.size()); // 有序
|
Map<String, String> templates = getTemplates(table.getFrontType());
|
||||||
TEMPLATES.forEach((vmPath, filePath) -> {
|
Map<String, String> result = Maps.newLinkedHashMapWithExpectedSize(templates.size()); // 有序
|
||||||
|
templates.forEach((vmPath, filePath) -> {
|
||||||
filePath = formatFilePath(filePath, bindingMap);
|
filePath = formatFilePath(filePath, bindingMap);
|
||||||
String content = templateEngine.getTemplate(vmPath).render(bindingMap);
|
String content = templateEngine.getTemplate(vmPath).render(bindingMap);
|
||||||
|
// 去除字段后面多余的 , 逗号
|
||||||
|
content = content.replaceAll(",\n}", "\n}").replaceAll(",\n }", "\n }");
|
||||||
result.put(filePath, content);
|
result.put(filePath, content);
|
||||||
});
|
});
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Map<String, String> getTemplates(Integer frontType) {
|
||||||
|
Map<String, String> templates = new LinkedHashMap<>();
|
||||||
|
templates.putAll(SERVER_TEMPLATES);
|
||||||
|
templates.putAll(FRONT_TEMPLATES.row(frontType));
|
||||||
|
return templates;
|
||||||
|
}
|
||||||
|
|
||||||
private String formatFilePath(String filePath, Map<String, Object> bindingMap) {
|
private String formatFilePath(String filePath, Map<String, Object> bindingMap) {
|
||||||
filePath = StrUtil.replace(filePath, "${basePackage}",
|
filePath = StrUtil.replace(filePath, "${basePackage}",
|
||||||
getStr(bindingMap, "basePackage").replaceAll("\\.", "/"));
|
getStr(bindingMap, "basePackage").replaceAll("\\.", "/"));
|
||||||
filePath = StrUtil.replace(filePath, "${classNameVar}",
|
filePath = StrUtil.replace(filePath, "${classNameVar}",
|
||||||
getStr(bindingMap, "classNameVar"));
|
getStr(bindingMap, "classNameVar"));
|
||||||
|
filePath = StrUtil.replace(filePath, "${simpleClassName}",
|
||||||
|
getStr(bindingMap, "simpleClassName"));
|
||||||
// sceneEnum 包含的字段
|
// sceneEnum 包含的字段
|
||||||
CodegenSceneEnum sceneEnum = (CodegenSceneEnum) bindingMap.get("sceneEnum");
|
CodegenSceneEnum sceneEnum = (CodegenSceneEnum) bindingMap.get("sceneEnum");
|
||||||
filePath = StrUtil.replace(filePath, "${sceneEnum.prefixClass}", sceneEnum.getPrefixClass());
|
filePath = StrUtil.replace(filePath, "${sceneEnum.prefixClass}", sceneEnum.getPrefixClass());
|
||||||
@ -239,6 +270,7 @@ public class CodegenEngine {
|
|||||||
return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
|
return "yudao-ui-${sceneEnum.basePackage}/" + // 顶级目录
|
||||||
"src/" + path;
|
"src/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String vue3TemplatePath(String path) {
|
private static String vue3TemplatePath(String path) {
|
||||||
return "codegen/vue3/" + path + ".vm";
|
return "codegen/vue3/" + path + ".vm";
|
||||||
}
|
}
|
||||||
@ -247,4 +279,8 @@ public class CodegenEngine {
|
|||||||
return "yudao-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
|
return "yudao-ui-${sceneEnum.basePackage}-vue3/" + // 顶级目录
|
||||||
"src/" + path;
|
"src/" + path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String vue3SchemaTemplatePath(String path) {
|
||||||
|
return "codegen/vue3_schema/" + path + ".vm";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,6 +128,7 @@ yudao:
|
|||||||
codegen:
|
codegen:
|
||||||
base-package: cn.iocoder.yudao
|
base-package: cn.iocoder.yudao
|
||||||
db-schemas: ${spring.datasource.dynamic.datasource.master.name}
|
db-schemas: ${spring.datasource.dynamic.datasource.master.name}
|
||||||
|
front-type: 10 # 前端模版的类型,参见 CodegenFrontTypeEnum 枚举类
|
||||||
error-code: # 错误码相关配置项
|
error-code: # 错误码相关配置项
|
||||||
constants-class-list:
|
constants-class-list:
|
||||||
- cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants
|
- cn.iocoder.yudao.module.infra.enums.ErrorCodeConstants
|
||||||
|
@ -1,17 +1,17 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName};
|
||||||
|
|
||||||
import org.springframework.web.bind.annotation.*;
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import javax.annotation.Resource;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
#if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end
|
#if ($sceneEnum.scene == 1)import org.springframework.security.access.prepost.PreAuthorize;#end
|
||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
|
||||||
import io.swagger.v3.oas.annotations.Parameter;
|
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import io.swagger.v3.oas.annotations.Parameter;
|
||||||
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
|
|
||||||
import jakarta.annotation.Resource;
|
import javax.validation.constraints.*;
|
||||||
import jakarta.servlet.http.HttpServletResponse;
|
import javax.validation.*;
|
||||||
import jakarta.validation.Valid;
|
import javax.servlet.http.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
@ -24,7 +24,6 @@ import ${ExcelUtilsClassName};
|
|||||||
import ${OperateLogClassName};
|
import ${OperateLogClassName};
|
||||||
import static ${OperateTypeEnumClassName}.*;
|
import static ${OperateTypeEnumClassName}.*;
|
||||||
|
|
||||||
import ${basePackage}.framework.operatelog.core.annotations.OperateLog;
|
|
||||||
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
import ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo.*;
|
||||||
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
import ${basePackage}.module.${table.moduleName}.dal.dataobject.${table.businessName}.${table.className}DO;
|
||||||
import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
|
import ${basePackage}.module.${table.moduleName}.convert.${table.businessName}.${table.className}Convert;
|
||||||
@ -42,18 +41,16 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
|
|||||||
|
|
||||||
@PostMapping("/create")
|
@PostMapping("/create")
|
||||||
@Operation(summary = "创建${table.classComment}")
|
@Operation(summary = "创建${table.classComment}")
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:create')")
|
|
||||||
#end
|
|
||||||
public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
|
public CommonResult<${primaryColumn.javaType}> create${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}CreateReqVO createReqVO) {
|
||||||
return success(${classNameVar}Service.create${simpleClassName}(createReqVO));
|
return success(${classNameVar}Service.create${simpleClassName}(createReqVO));
|
||||||
}
|
}
|
||||||
|
|
||||||
@PutMapping("/update")
|
@PutMapping("/update")
|
||||||
@Operation(summary = "更新${table.classComment}")
|
@Operation(summary = "更新${table.classComment}")
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:update')")
|
|
||||||
#end
|
|
||||||
public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
|
public CommonResult<Boolean> update${simpleClassName}(@Valid @RequestBody ${sceneEnum.prefixClass}${table.className}UpdateReqVO updateReqVO) {
|
||||||
${classNameVar}Service.update${simpleClassName}(updateReqVO);
|
${classNameVar}Service.update${simpleClassName}(updateReqVO);
|
||||||
return success(true);
|
return success(true);
|
||||||
@ -62,9 +59,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
|
|||||||
@DeleteMapping("/delete")
|
@DeleteMapping("/delete")
|
||||||
@Operation(summary = "删除${table.classComment}")
|
@Operation(summary = "删除${table.classComment}")
|
||||||
@Parameter(name = "id", description = "编号", required = true)
|
@Parameter(name = "id", description = "编号", required = true)
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:delete')")
|
|
||||||
#end
|
|
||||||
public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
public CommonResult<Boolean> delete${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
||||||
${classNameVar}Service.delete${simpleClassName}(id);
|
${classNameVar}Service.delete${simpleClassName}(id);
|
||||||
return success(true);
|
return success(true);
|
||||||
@ -73,9 +69,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
|
|||||||
@GetMapping("/get")
|
@GetMapping("/get")
|
||||||
@Operation(summary = "获得${table.classComment}")
|
@Operation(summary = "获得${table.classComment}")
|
||||||
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
@Parameter(name = "id", description = "编号", required = true, example = "1024")
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
|
||||||
#end
|
|
||||||
public CommonResult<${sceneEnum.prefixClass}${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
public CommonResult<${sceneEnum.prefixClass}${table.className}RespVO> get${simpleClassName}(@RequestParam("id") ${primaryColumn.javaType} id) {
|
||||||
${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
|
${table.className}DO ${classNameVar} = ${classNameVar}Service.get${simpleClassName}(id);
|
||||||
return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
|
return success(${table.className}Convert.INSTANCE.convert(${classNameVar}));
|
||||||
@ -84,9 +79,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
|
|||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
@Operation(summary = "获得${table.classComment}列表")
|
@Operation(summary = "获得${table.classComment}列表")
|
||||||
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
|
@Parameter(name = "ids", description = "编号列表", required = true, example = "1024,2048")
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
|
||||||
#end
|
|
||||||
public CommonResult<List<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
|
public CommonResult<List<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}List(@RequestParam("ids") Collection<${primaryColumn.javaType}> ids) {
|
||||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(ids);
|
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(ids);
|
||||||
return success(${table.className}Convert.INSTANCE.convertList(list));
|
return success(${table.className}Convert.INSTANCE.convertList(list));
|
||||||
@ -94,9 +88,8 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
|
|||||||
|
|
||||||
@GetMapping("/page")
|
@GetMapping("/page")
|
||||||
@Operation(summary = "获得${table.classComment}分页")
|
@Operation(summary = "获得${table.classComment}分页")
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:query')")
|
|
||||||
#end
|
|
||||||
public CommonResult<PageResult<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageVO) {
|
public CommonResult<PageResult<${sceneEnum.prefixClass}${table.className}RespVO>> get${simpleClassName}Page(@Valid ${sceneEnum.prefixClass}${table.className}PageReqVO pageVO) {
|
||||||
PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(pageVO);
|
PageResult<${table.className}DO> pageResult = ${classNameVar}Service.get${simpleClassName}Page(pageVO);
|
||||||
return success(${table.className}Convert.INSTANCE.convertPage(pageResult));
|
return success(${table.className}Convert.INSTANCE.convertPage(pageResult));
|
||||||
@ -104,16 +97,15 @@ public class ${sceneEnum.prefixClass}${table.className}Controller {
|
|||||||
|
|
||||||
@GetMapping("/export-excel")
|
@GetMapping("/export-excel")
|
||||||
@Operation(summary = "导出${table.classComment} Excel")
|
@Operation(summary = "导出${table.classComment} Excel")
|
||||||
#if ($sceneEnum.scene == 1)
|
#if ($sceneEnum.scene == 1) @PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")#end
|
||||||
@PreAuthorize("@ss.hasPermission('${permissionPrefix}:export')")
|
|
||||||
#end
|
|
||||||
@OperateLog(type = EXPORT)
|
@OperateLog(type = EXPORT)
|
||||||
public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO,
|
public void export${simpleClassName}Excel(@Valid ${sceneEnum.prefixClass}${table.className}ExportReqVO exportReqVO,
|
||||||
HttpServletResponse response) throws IOException {
|
HttpServletResponse response) throws IOException {
|
||||||
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(exportReqVO);
|
List<${table.className}DO> list = ${classNameVar}Service.get${simpleClassName}List(exportReqVO);
|
||||||
// 导出 Excel
|
// 导出 Excel
|
||||||
List<${sceneEnum.prefixClass}${table.className}ExcelVO> datas = ${table.className}Convert.INSTANCE.convertList02(list);
|
List<${sceneEnum.prefixClass}${table.className}ExcelVO> datas = ${table.className}Convert.INSTANCE.convertList02(list);
|
||||||
ExcelUtils.write(response, "${table.classComment}.xls","数据", ${sceneEnum.prefixClass}${table.className}ExcelVO.class, datas);
|
ExcelUtils.write(response, "${table.classComment}.xls", "数据", ${sceneEnum.prefixClass}${table.className}ExcelVO.class, datas);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
## @formatter:off
|
|
||||||
## 提供给 baseVO、createVO、updateVO 生成字段
|
## 提供给 baseVO、createVO、updateVO 生成字段
|
||||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||||
#if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解
|
#if (!${column.nullable})## 判断 @NotEmpty 和 @NotNull 注解
|
||||||
#if (${field.fieldType} == 'String')
|
#if (${field.fieldType} == 'String')
|
||||||
@NotEmpty(message = "${column.columnComment}不能为空")
|
@NotEmpty(message = "${column.columnComment}不能为空")
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
@ -11,11 +11,11 @@ import java.math.BigDecimal;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import javax.validation.constraints.*;
|
||||||
import jakarta.validation.constraints.*;
|
|
||||||
## 处理 Date 字段的引入
|
## 处理 Date 字段的引入
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if (${column.createOperation} && ${column.updateOperation} && ${column.listOperationResult} && ${column.javaType} == "LocalDateTime")## 时间类型
|
#if (${column.createOperation} && ${column.updateOperation} && ${column.listOperationResult}
|
||||||
|
&& ${column.javaType} == "LocalDateTime")## 时间类型
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
|
||||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import jakarta.validation.constraints.*;
|
import javax.validation.constraints.*;
|
||||||
## 处理 Date 字段的引入
|
## 处理 Date 字段的引入
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if (${column.createOperation} && (!${column.updateOperation} || !${column.listOperationResult}) && ${column.javaType} == "LocalDateTime")## 时间类型
|
#if (${column.createOperation} && (!${column.updateOperation} || !${column.listOperationResult})
|
||||||
|
&& ${column.javaType} == "LocalDateTime")## 时间类型
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
@ -15,7 +15,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@Schema(name = "${sceneEnum.name} - ${table.classComment}创建 Request VO")
|
@Schema(description = "${sceneEnum.name} - ${table.classComment}创建 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
@ -11,6 +11,7 @@ import java.math.BigDecimal;
|
|||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
import com.alibaba.excel.annotation.ExcelProperty;
|
import com.alibaba.excel.annotation.ExcelProperty;
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if ("$!column.dictType" != "")## 有设置数据字典
|
#if ("$!column.dictType" != "")## 有设置数据字典
|
||||||
@ -22,10 +23,10 @@ import ${DictConvertClassName};
|
|||||||
#end
|
#end
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ${table.classComment} Excel VO
|
* ${table.classComment} Excel VO
|
||||||
*
|
*
|
||||||
* @author ${table.author}
|
* @author ${table.author}
|
||||||
*/
|
*/
|
||||||
@Data
|
@Data
|
||||||
public class ${sceneEnum.prefixClass}${table.className}ExcelVO {
|
public class ${sceneEnum.prefixClass}${table.className}ExcelVO {
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -21,7 +20,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|||||||
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@Schema(name = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO", description = "参数和 ${table.className}PageReqVO 是一致的")
|
@Schema(description = "${sceneEnum.name} - ${table.classComment} Excel 导出 Request VO,参数和 ${table.className}PageReqVO 是一致的")
|
||||||
@Data
|
@Data
|
||||||
public class ${sceneEnum.prefixClass}${table.className}ExportReqVO {
|
public class ${sceneEnum.prefixClass}${table.className}ExportReqVO {
|
||||||
|
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
@ -21,7 +20,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|||||||
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
private ${column.javaType}#if ("$!prefix" != "") ${prefix}${JavaField}#else ${column.javaField}#end;
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@Schema(name = "${sceneEnum.name} - ${table.classComment}分页 Request VO")
|
@Schema(description = "${sceneEnum.name} - ${table.classComment}分页 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
import lombok.*;
|
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
|
import lombok.*;
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if (${column.javaType} == "LocalDateTime")
|
#if (${column.javaType} == "LocalDateTime")
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
@ -10,7 +9,7 @@ import java.time.LocalDateTime;
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@Schema(name = "${sceneEnum.name} - ${table.classComment} Response VO")
|
@Schema(description = "${sceneEnum.name} - ${table.classComment} Response VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
@ -18,7 +17,7 @@ public class ${sceneEnum.prefixClass}${table.className}RespVO extends ${sceneEnu
|
|||||||
|
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if (${column.listOperationResult} && (!${column.createOperation} || !${column.updateOperation}))##不是通用字段
|
#if (${column.listOperationResult} && (!${column.createOperation} || !${column.updateOperation}))##不是通用字段
|
||||||
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), requiredMode = Schema.RequiredMode.REQUIRED#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
@Schema(description = "${column.columnComment}"#if (!${column.nullable}), required = true#end#if ("$!column.example" != ""), example = "${column.example}"#end)
|
||||||
private ${column.javaType} ${column.javaField};
|
private ${column.javaType} ${column.javaField};
|
||||||
|
|
||||||
#end
|
#end
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
## @formatter:off
|
|
||||||
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
package ${basePackage}.module.${table.moduleName}.controller.${sceneEnum.basePackage}.${table.businessName}.vo;
|
||||||
|
|
||||||
|
import io.swagger.v3.oas.annotations.media.Schema;
|
||||||
import lombok.*;
|
import lombok.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import io.swagger.v3.oas.annotations.media.Schema;
|
import javax.validation.constraints.*;
|
||||||
import jakarta.validation.constraints.*;
|
|
||||||
## 处理 Date 字段的引入
|
## 处理 Date 字段的引入
|
||||||
#foreach ($column in $columns)
|
#foreach ($column in $columns)
|
||||||
#if (${column.updateOperation} && (!${column.createOperation} || !${column.listOperationResult}) && ${column.javaType} == "LocalDateTime")## 时间类型
|
#if (${column.updateOperation} && (!${column.createOperation} || !${column.listOperationResult})
|
||||||
|
&& ${column.javaType} == "LocalDateTime")## 时间类型
|
||||||
import org.springframework.format.annotation.DateTimeFormat;
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import java.time.LocalDateTime;
|
import java.time.LocalDateTime;
|
||||||
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
||||||
@ -15,7 +15,7 @@ import static ${DateUtilsClassName}.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
|
|||||||
#end
|
#end
|
||||||
#end
|
#end
|
||||||
|
|
||||||
@Schema(name = "${sceneEnum.name} - ${table.classComment}更新 Request VO")
|
@Schema(description = "${sceneEnum.name} - ${table.classComment}更新 Request VO")
|
||||||
@Data
|
@Data
|
||||||
@EqualsAndHashCode(callSuper = true)
|
@EqualsAndHashCode(callSuper = true)
|
||||||
@ToString(callSuper = true)
|
@ToString(callSuper = true)
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
-- 菜单 SQL
|
-- 菜单 SQL
|
||||||
INSERT INTO system_menu(
|
INSERT INTO system_menu(
|
||||||
name, permission, type, sort, parent_id,
|
name, permission, type, sort, parent_id,
|
||||||
path, icon, component, status
|
path, icon, component, status, component_name
|
||||||
)
|
)
|
||||||
VALUES (
|
VALUES (
|
||||||
'${table.classComment}管理', '', 2, 0, ${table.parentMenuId},
|
'${table.classComment}管理', '', 2, 0, ${table.parentMenuId},
|
||||||
'${simpleClassName_strikeCase}', '', '${table.moduleName}/${classNameVar}/index', 0
|
'${simpleClassName_strikeCase}', '', '${table.moduleName}/${classNameVar}/index', 0, '${table.className}'
|
||||||
);
|
);
|
||||||
|
|
||||||
-- 按钮父菜单ID
|
-- 按钮父菜单ID
|
||||||
|
@ -14,61 +14,32 @@ export interface ${simpleClassName}VO {
|
|||||||
#end
|
#end
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ${simpleClassName}PageReqVO extends PageParam {
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if (${column.listOperation})##查询操作
|
|
||||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
|
||||||
${column.javaField}?: number
|
|
||||||
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
|
|
||||||
${column.javaField}?: Date[]
|
|
||||||
#else
|
|
||||||
${column.javaField}?: ${column.javaType.toLowerCase()}
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ${simpleClassName}ExcelReqVO {
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if (${column.listOperation})##查询操作
|
|
||||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
|
||||||
${column.javaField}?: number
|
|
||||||
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
|
|
||||||
${column.javaField}?: Date[]
|
|
||||||
#else
|
|
||||||
${column.javaField}?: ${column.javaType.toLowerCase()}
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
#set ($baseURL = "/${table.moduleName}/${simpleClassName_strikeCase}")
|
|
||||||
|
|
||||||
// 查询${table.classComment}列表
|
// 查询${table.classComment}列表
|
||||||
export const get${simpleClassName}PageApi = async (params: ${simpleClassName}PageReqVO) => {
|
export const get${simpleClassName}Page = async (params: ${simpleClassName}PageReqVO) => {
|
||||||
return await request.get({ url: '${baseURL}/page', params })
|
return await request.get({ url: '${baseURL}/page', params })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 查询${table.classComment}详情
|
// 查询${table.classComment}详情
|
||||||
export const get${simpleClassName}Api = async (id: number) => {
|
export const get${simpleClassName} = async (id: number) => {
|
||||||
return await request.get({ url: '${baseURL}/get?id=' + id })
|
return await request.get({ url: '${baseURL}/get?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增${table.classComment}
|
// 新增${table.classComment}
|
||||||
export const create${simpleClassName}Api = async (data: ${simpleClassName}VO) => {
|
export const create${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||||
return await request.post({ url: '${baseURL}/create', data })
|
return await request.post({ url: '${baseURL}/create', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改${table.classComment}
|
// 修改${table.classComment}
|
||||||
export const update${simpleClassName}Api = async (data: ${simpleClassName}VO) => {
|
export const update${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||||
return await request.put({ url: '${baseURL}/update', data })
|
return await request.put({ url: '${baseURL}/update', data })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 删除${table.classComment}
|
// 删除${table.classComment}
|
||||||
export const delete${simpleClassName}Api = async (id: number) => {
|
export const delete${simpleClassName} = async (id: number) => {
|
||||||
return await request.delete({ url: '${baseURL}/delete?id=' + id })
|
return await request.delete({ url: '${baseURL}/delete?id=' + id })
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出${table.classComment} Excel
|
// 导出${table.classComment} Excel
|
||||||
export const export${simpleClassName}Api = async (params: ${simpleClassName}ExcelReqVO) => {
|
export const export${simpleClassName}Api = async (params) => {
|
||||||
return await request.download({ url: '${baseURL}/export-excel', params })
|
return await request.download({ url: '${baseURL}/export-excel', params })
|
||||||
}
|
}
|
||||||
|
@ -1,41 +0,0 @@
|
|||||||
export type ${simpleClassName}VO = {
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if ($column.createOperation || $column.updateOperation)
|
|
||||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
|
|
||||||
${column.javaField}: number
|
|
||||||
#elseif(${column.javaType.toLowerCase()} == "date")
|
|
||||||
${column.javaField}: string
|
|
||||||
#else
|
|
||||||
${column.javaField}: ${column.javaType.toLowerCase()}
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ${simpleClassName}PageReqVO = {
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if (${column.listOperation})##查询操作
|
|
||||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
|
|
||||||
${column.javaField}: number
|
|
||||||
#elseif(${column.javaType.toLowerCase()} == "date")
|
|
||||||
${column.javaField}: string
|
|
||||||
#else
|
|
||||||
${column.javaField}: ${column.javaType.toLowerCase()}
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ${simpleClassName}ExcelReqVO = {
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if (${column.listOperation})##查询操作
|
|
||||||
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
|
|
||||||
${column.javaField}: number
|
|
||||||
#elseif(${column.javaType.toLowerCase()} == "date")
|
|
||||||
${column.javaField}: string
|
|
||||||
#else
|
|
||||||
${column.javaField}: ${column.javaType.toLowerCase()}
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
}
|
|
@ -1,110 +0,0 @@
|
|||||||
import { reactive } from 'vue'
|
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
|
||||||
import { DICT_TYPE } from '@/utils/dict'
|
|
||||||
import { required } from '@/utils/formRules'
|
|
||||||
import { VxeCrudSchema, useVxeCrudSchemas } from '@/hooks/web/useVxeCrudSchemas'
|
|
||||||
const { t } = useI18n() // 国际化
|
|
||||||
// 表单校验
|
|
||||||
export const rules = reactive({
|
|
||||||
#foreach ($column in $columns)
|
|
||||||
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
|
||||||
#set($comment=$column.columnComment)
|
|
||||||
$column.javaField: [required],
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
})
|
|
||||||
// CrudSchema
|
|
||||||
const crudSchemas = reactive<VxeCrudSchema>({
|
|
||||||
primaryKey: 'id', // 默认的主键ID
|
|
||||||
primaryTitle: t('common.index'), // 默认显示的值
|
|
||||||
primaryType: 'seq', // 默认为seq,序号模式
|
|
||||||
action: true,
|
|
||||||
actionWidth: '200', // 3个按钮默认200,如有删减对应增减即可
|
|
||||||
columns: [
|
|
||||||
#foreach($column in $columns)
|
|
||||||
#if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
|
|
||||||
#set ($dictType = $column.dictType)
|
|
||||||
#if(!$column.primaryKey)
|
|
||||||
{
|
|
||||||
title: '${column.columnComment}',
|
|
||||||
field: '${column.javaField}',
|
|
||||||
#if (!$column.listOperationResult)
|
|
||||||
isTable: false,
|
|
||||||
#end
|
|
||||||
#if ("" != $dictType)## 有数据字典
|
|
||||||
dictType: DICT_TYPE.$dictType.toUpperCase(),
|
|
||||||
#if (${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")
|
|
||||||
dictClass: 'number',
|
|
||||||
#else
|
|
||||||
dictClass: 'string',
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#if (!$column.createOperation && !$column.updateOperation)
|
|
||||||
isForm: false,
|
|
||||||
#elseif(!("" != $column.dictType))
|
|
||||||
#if (${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
|
|
||||||
form: {
|
|
||||||
component: 'DatePicker',
|
|
||||||
componentProps: {
|
|
||||||
type: 'datetime',
|
|
||||||
valueFormat: 'x'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
#elseif($column.htmlType == "editor")## 文本编辑器
|
|
||||||
form: {
|
|
||||||
component: 'Editor',
|
|
||||||
colProps: {
|
|
||||||
span: 24
|
|
||||||
},
|
|
||||||
componentProps: {
|
|
||||||
valueHtml: ''
|
|
||||||
}
|
|
||||||
},
|
|
||||||
#elseif($column.htmlType == "textarea")## 文本框
|
|
||||||
form: {
|
|
||||||
component: 'Input',
|
|
||||||
componentProps: {
|
|
||||||
type: 'textarea',
|
|
||||||
rows: 4
|
|
||||||
},
|
|
||||||
colProps: {
|
|
||||||
span: 24
|
|
||||||
}
|
|
||||||
},
|
|
||||||
#elseif(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer")## 数字类型
|
|
||||||
form: {
|
|
||||||
component: 'InputNumber',
|
|
||||||
value: 0
|
|
||||||
},
|
|
||||||
#elseif($column.htmlType == "imageUpload")## 图片上传
|
|
||||||
form: {
|
|
||||||
component: 'UploadImg' // 单图上传,多图为UploadImgs
|
|
||||||
},
|
|
||||||
#elseif($column.htmlType == "fileUpload")## 图片上传
|
|
||||||
form: {
|
|
||||||
component: 'UploadFile'
|
|
||||||
},
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#if ($column.listOperation)
|
|
||||||
#if($column.htmlType == "input")
|
|
||||||
isSearch: true,
|
|
||||||
#elseif("" != $dictType)
|
|
||||||
isSearch: true,
|
|
||||||
#elseif($column.htmlType == "datetime")
|
|
||||||
formatter: 'formatDate',
|
|
||||||
search: {
|
|
||||||
show: true,
|
|
||||||
itemRender: {
|
|
||||||
name: 'XDataTimePicker'
|
|
||||||
}
|
|
||||||
},
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
},
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
#end
|
|
||||||
]
|
|
||||||
})
|
|
||||||
export const { allSchemas } = useVxeCrudSchemas(crudSchemas)
|
|
@ -0,0 +1,234 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<el-form
|
||||||
|
ref="formRef"
|
||||||
|
:model="formData"
|
||||||
|
:rules="formRules"
|
||||||
|
label-width="100px"
|
||||||
|
v-loading="formLoading"
|
||||||
|
>
|
||||||
|
#set ($dictMethods = [])## 使用到的 dict 字典方法
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "getIntDictOptions")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "getStrDictOptions")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "getBoolDictOptions")
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input" && !$column.primaryKey)## 忽略主键,不用在表单里
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
#set ($hasImageUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<UploadImg v-model="formData.${javaField}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
#set ($hasFileUploadColumn = true)
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<UploadFile v-model="formData.${javaField}" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
<el-form-item label="${comment}">
|
||||||
|
<Editor :model-value="formData.${javaField}" height="150px" />
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-select v-model="formData.${javaField}" placeholder="请选择${comment}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
#if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
|
||||||
|
#set($ignore = $dictMethods.add($dictMethod) )
|
||||||
|
#end
|
||||||
|
<el-option
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-checkbox-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
#if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
|
||||||
|
#set($ignore = $dictMethods.add($dictMethod) )
|
||||||
|
#end
|
||||||
|
<el-checkbox
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-checkbox>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-checkbox>请选择字典生成</el-checkbox>
|
||||||
|
#end
|
||||||
|
</el-checkbox-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-radio-group v-model="formData.${javaField}">
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
#if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
|
||||||
|
#set($ignore = $dictMethods.add($dictMethod) )
|
||||||
|
#end
|
||||||
|
<el-radio
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.value"
|
||||||
|
>
|
||||||
|
{{ dict.label }}
|
||||||
|
</el-radio>
|
||||||
|
#else##没数据字典
|
||||||
|
<el-radio label="1">请选择字典生成</el-radio>
|
||||||
|
#end
|
||||||
|
</el-radio-group>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="formData.${javaField}"
|
||||||
|
type="date"
|
||||||
|
value-format="timestamp"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input v-model="formData.${javaField}" type="textarea" placeholder="请输入${comment}" />
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
</el-form>
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
#if ($dictMethods.size() > 0)
|
||||||
|
import { DICT_TYPE#foreach ($dictMethod in $dictMethods), ${dictMethod}#end } from '@/utils/dict'
|
||||||
|
#end
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
|
||||||
|
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formData = ref({
|
||||||
|
#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($listOperationLastIndex = $foreach.index)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: []#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
const formRules = reactive({
|
||||||
|
#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set ($listOperationLastIndex = $foreach.index)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [{ required: true, message: '${comment}不能为空', trigger: #if($column.htmlType == 'select')'change'#else'blur'#end }]#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
resetForm()
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
formData.value = await ${simpleClassName}Api.get${simpleClassName}(id)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef) return
|
||||||
|
const valid = await formRef.value.validate()
|
||||||
|
if (!valid) return
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formData.value as unknown as ${simpleClassName}Api.${simpleClassName}VO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ${simpleClassName}Api.create${simpleClassName}(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ${simpleClassName}Api.update${simpleClassName}(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 重置表单 */
|
||||||
|
const resetForm = () => {
|
||||||
|
formData.value = {
|
||||||
|
#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#set ($listOperationLastIndex = $foreach.index)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if ($column.htmlType == "checkbox")
|
||||||
|
$column.javaField: []#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#else
|
||||||
|
$column.javaField: undefined#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
formRef.value?.resetFields()
|
||||||
|
}
|
||||||
|
</script>
|
@ -1,177 +1,285 @@
|
|||||||
<template>
|
<template>
|
||||||
<ContentWrap>
|
<ContentWrap>
|
||||||
<!-- 列表 -->
|
<!-- 搜索工作栏 -->
|
||||||
<vxe-grid ref="xGrid" v-bind="gridOptions" class="xtable-scrollbar">
|
<el-form
|
||||||
<template #toolbar_buttons>
|
class="-mb-15px"
|
||||||
<!-- 操作:新增 -->
|
:model="queryParams"
|
||||||
<XButton
|
ref="queryFormRef"
|
||||||
|
:inline="true"
|
||||||
|
label-width="68px"
|
||||||
|
>
|
||||||
|
#set ($dictMethods = [])## 使用到的 dict 字典方法
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
#set ($AttrName = $column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
|
#set ($comment = $column.columnComment)
|
||||||
|
#set ($dictMethod = "getDictOptions")## 计算使用哪个 dict 字典方法
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
#set ($dictMethod = "getIntDictOptions")
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
#set ($dictMethod = "getStrDictOptions")
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
#set ($dictMethod = "getBoolDictOptions")
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "input")
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-input
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
placeholder="请输入${comment}"
|
||||||
|
clearable
|
||||||
|
@keyup.enter="handleQuery"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif ($column.htmlType == "select" || $column.htmlType == "radio")
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
#if ($javaField.length() + $comment.length() > 8)
|
||||||
|
<el-select
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
placeholder="请选择${comment}"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
>
|
||||||
|
#else
|
||||||
|
<el-select v-model="queryParams.${javaField}" placeholder="请选择${comment}" clearable class="!w-240px">
|
||||||
|
#end
|
||||||
|
#if ("" != $dictType)## 设置了 dictType 数据字典的情况
|
||||||
|
#if (!$dictMethods.contains($dictMethod))## 如果不存在,则添加到 dictMethods 数组中,后续好 import
|
||||||
|
#set($ignore = $dictMethods.add($dictMethod) )
|
||||||
|
#end
|
||||||
|
<el-option
|
||||||
|
v-for="dict in $dictMethod(DICT_TYPE.$dictType.toUpperCase())"
|
||||||
|
:key="dict.value"
|
||||||
|
:label="dict.label"
|
||||||
|
:value="dict.value"
|
||||||
|
/>
|
||||||
|
#else## 未设置 dictType 数据字典的情况
|
||||||
|
<el-option label="请选择字典生成" value="" />
|
||||||
|
#end
|
||||||
|
</el-select>
|
||||||
|
</el-form-item>
|
||||||
|
#elseif($column.htmlType == "datetime")
|
||||||
|
#if ($column.listOperationCondition != "BETWEEN")## 非范围
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
value-format="yyyy-MM-dd"
|
||||||
|
type="date"
|
||||||
|
placeholder="选择${comment}"
|
||||||
|
clearable
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#else## 范围
|
||||||
|
<el-form-item label="${comment}" prop="${javaField}">
|
||||||
|
<el-date-picker
|
||||||
|
v-model="queryParams.${javaField}"
|
||||||
|
value-format="yyyy-MM-dd HH:mm:ss"
|
||||||
|
type="daterange"
|
||||||
|
start-placeholder="开始日期"
|
||||||
|
end-placeholder="结束日期"
|
||||||
|
:default-time="[new Date('1 00:00:00'), new Date('1 23:59:59')]"
|
||||||
|
class="!w-240px"
|
||||||
|
/>
|
||||||
|
</el-form-item>
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<el-form-item>
|
||||||
|
<el-button @click="handleQuery"><Icon icon="ep:search" class="mr-5px" /> 搜索</el-button>
|
||||||
|
<el-button @click="resetQuery"><Icon icon="ep:refresh" class="mr-5px" /> 重置</el-button>
|
||||||
|
#if ($permissionPrefix.length() <= 12)
|
||||||
|
<el-button type="primary" @click="openForm('create')" v-hasPermi="['${permissionPrefix}:create']">
|
||||||
|
#else
|
||||||
|
<el-button
|
||||||
type="primary"
|
type="primary"
|
||||||
preIcon="ep:zoom-in"
|
plain
|
||||||
:title="t('action.add')"
|
@click="openForm('create')"
|
||||||
v-hasPermi="['${permissionPrefix}:create']"
|
v-hasPermi="['${permissionPrefix}:create']"
|
||||||
@click="handleCreate()"
|
>
|
||||||
/>
|
#end
|
||||||
<!-- 操作:导出 -->
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
<XButton
|
</el-button>
|
||||||
type="warning"
|
<el-button
|
||||||
preIcon="ep:download"
|
type="success"
|
||||||
:title="t('action.export')"
|
plain
|
||||||
|
@click="handleExport"
|
||||||
|
:loading="exportLoading"
|
||||||
v-hasPermi="['${permissionPrefix}:export']"
|
v-hasPermi="['${permissionPrefix}:export']"
|
||||||
@click="handleExport()"
|
>
|
||||||
/>
|
<Icon icon="ep:download" class="mr-5px" /> 导出
|
||||||
</template>
|
</el-button>
|
||||||
<template #actionbtns_default="{ row }">
|
</el-form-item>
|
||||||
<!-- 操作:修改 -->
|
</el-form>
|
||||||
<XTextButton
|
|
||||||
preIcon="ep:edit"
|
|
||||||
:title="t('action.edit')"
|
|
||||||
v-hasPermi="['${permissionPrefix}:update']"
|
|
||||||
@click="handleUpdate(row.id)"
|
|
||||||
/>
|
|
||||||
<!-- 操作:详情 -->
|
|
||||||
<XTextButton
|
|
||||||
preIcon="ep:view"
|
|
||||||
:title="t('action.detail')"
|
|
||||||
v-hasPermi="['${permissionPrefix}:query']"
|
|
||||||
@click="handleDetail(row.id)"
|
|
||||||
/>
|
|
||||||
<!-- 操作:删除 -->
|
|
||||||
<XTextButton
|
|
||||||
preIcon="ep:delete"
|
|
||||||
:title="t('action.del')"
|
|
||||||
v-hasPermi="['${permissionPrefix}:delete']"
|
|
||||||
@click="handleDelete(row.id)"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</vxe-grid>
|
|
||||||
</ContentWrap>
|
</ContentWrap>
|
||||||
<!-- 弹窗 -->
|
|
||||||
<XModal id="${classNameVar}Model" :loading="modelLoading" v-model="modelVisible" :title="modelTitle">
|
<!-- 列表 -->
|
||||||
<!-- 表单:添加/修改 -->
|
<ContentWrap>
|
||||||
<Form
|
<el-table v-loading="loading" :data="list">
|
||||||
ref="formRef"
|
#foreach($column in $columns)
|
||||||
v-if="['create', 'update'].includes(actionType)"
|
#if ($column.listOperationResult)
|
||||||
:schema="allSchemas.formSchema"
|
#set ($dictType=$column.dictType)
|
||||||
:rules="rules"
|
#set ($javaField = $column.javaField)
|
||||||
/>
|
#set ($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||||
<!-- 表单:详情 -->
|
#set ($comment=$column.columnComment)
|
||||||
<Descriptions
|
#if ($column.javaType == "LocalDateTime")## 时间类型
|
||||||
v-if="actionType === 'detail'"
|
<el-table-column
|
||||||
:schema="allSchemas.detailSchema"
|
label="${comment}"
|
||||||
:data="detailData"
|
align="center"
|
||||||
/>
|
prop="${javaField}"
|
||||||
<template #footer>
|
:formatter="dateFormatter"
|
||||||
<!-- 按钮:保存 -->
|
|
||||||
<XButton
|
|
||||||
v-if="['create', 'update'].includes(actionType)"
|
|
||||||
type="primary"
|
|
||||||
:title="t('action.save')"
|
|
||||||
:loading="actionLoading"
|
|
||||||
@click="submitForm()"
|
|
||||||
/>
|
/>
|
||||||
<!-- 按钮:关闭 -->
|
#elseif("" != $column.dictType)## 数据字典
|
||||||
<XButton :loading="actionLoading" :title="t('dialog.close')" @click="modelVisible = false" />
|
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||||
</template>
|
<template #default="scope">
|
||||||
</XModal>
|
<dict-tag :type="DICT_TYPE.$dictType.toUpperCase()" :value="scope.row.${column.javaField}" />
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
#else
|
||||||
|
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
<el-table-column label="操作" align="center">
|
||||||
|
<template #default="scope">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', scope.row.id)"
|
||||||
|
v-hasPermi="['${permissionPrefix}:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
@click="handleDelete(scope.row.id)"
|
||||||
|
v-hasPermi="['${permissionPrefix}:delete']"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</el-table-column>
|
||||||
|
</el-table>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<Pagination
|
||||||
|
:total="total"
|
||||||
|
v-model:page="queryParams.pageNo"
|
||||||
|
v-model:limit="queryParams.pageSize"
|
||||||
|
@pagination="getList"
|
||||||
|
/>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts" name="${simpleClassName}">
|
|
||||||
// 全局相关的 import
|
<script setup lang="ts" name="${table.className}">
|
||||||
import { ref, unref } from 'vue'
|
#if ($dictMethods.size() > 0)
|
||||||
import { useI18n } from '@/hooks/web/useI18n'
|
import { DICT_TYPE#foreach ($dictMethod in $dictMethods), ${dictMethod}#end } from '@/utils/dict'
|
||||||
import { useMessage } from '@/hooks/web/useMessage'
|
#end
|
||||||
import { useVxeGrid } from '@/hooks/web/useVxeGrid'
|
#foreach ($column in $columns)
|
||||||
import { VxeGridInstance } from 'vxe-table'
|
#if ($column.listOperationResult && $column.htmlType == "datetime")
|
||||||
import { FormExpose } from '@/components/Form'
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
// 业务相关的 import
|
#break
|
||||||
import { rules, allSchemas } from './${classNameVar}.data'
|
#end
|
||||||
|
#end
|
||||||
|
import download from '@/utils/download'
|
||||||
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
|
||||||
|
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
|
||||||
const { t } = useI18n() // 国际化
|
|
||||||
const message = useMessage() // 消息弹窗
|
const message = useMessage() // 消息弹窗
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
|
||||||
// 列表相关的变量
|
const loading = ref(true) // 列表的加载中
|
||||||
const xGrid = ref<VxeGridInstance>() // 列表 Grid Ref
|
const total = ref(0) // 列表的总页数
|
||||||
const { gridOptions, getList, deleteData, exportList } = useVxeGrid<${simpleClassName}Api.${simpleClassName}VO>({
|
const list = ref([]) // 列表的数据
|
||||||
allSchemas: allSchemas,
|
const queryParams = reactive({
|
||||||
getListApi: ${simpleClassName}Api.get${simpleClassName}PageApi,
|
pageNo: 1,
|
||||||
deleteApi: ${simpleClassName}Api.delete${simpleClassName}Api,
|
pageSize: 10,
|
||||||
exportListApi: ${simpleClassName}Api.export${simpleClassName}Api
|
#set ($listOperationLastIndex = -1)## 求最后一个需要 , 的地方
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#set ($listOperationLastIndex = $foreach.index)
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperation)
|
||||||
|
#if ($column.listOperationCondition != 'BETWEEN')
|
||||||
|
$column.javaField: null#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#end
|
||||||
|
#if ($column.htmlType == "datetime" || $column.listOperationCondition == "BETWEEN")
|
||||||
|
$column.javaField: []#if($foreach.index < $listOperationLastIndex),#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
})
|
})
|
||||||
|
const queryFormRef = ref() // 搜索的表单
|
||||||
|
const exportLoading = ref(false) // 导出的加载中
|
||||||
|
|
||||||
// 弹窗相关的变量
|
/** 查询列表 */
|
||||||
const modelVisible = ref(false) // 是否显示弹出层
|
const getList = async () => {
|
||||||
const modelTitle = ref('edit') // 弹出层标题
|
loading.value = true
|
||||||
const modelLoading = ref(false) // 弹出层loading
|
try {
|
||||||
const actionType = ref('') // 操作按钮的类型
|
const data = await ${simpleClassName}Api.get${simpleClassName}Page(queryParams)
|
||||||
const actionLoading = ref(false) // 按钮 Loading
|
list.value = data.list
|
||||||
const formRef = ref<FormExpose>() // 表单 Ref
|
total.value = data.total
|
||||||
const detailData = ref() // 详情 Ref
|
} finally {
|
||||||
|
loading.value = false
|
||||||
// 设置标题
|
}
|
||||||
const setDialogTile = (type: string) => {
|
|
||||||
modelLoading.value = true
|
|
||||||
modelTitle.value = t('action.' + type)
|
|
||||||
actionType.value = type
|
|
||||||
modelVisible.value = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 新增操作
|
/** 搜索按钮操作 */
|
||||||
const handleCreate = () => {
|
const handleQuery = () => {
|
||||||
setDialogTile('create')
|
queryParams.pageNo = 1
|
||||||
modelLoading.value = false
|
getList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// 导出操作
|
/** 重置按钮操作 */
|
||||||
|
const resetQuery = () => {
|
||||||
|
queryFormRef.value.resetFields()
|
||||||
|
handleQuery()
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = async (id: number) => {
|
||||||
|
try {
|
||||||
|
// 删除的二次确认
|
||||||
|
await message.delConfirm()
|
||||||
|
// 发起删除
|
||||||
|
await ${simpleClassName}Api.delete${simpleClassName}(id)
|
||||||
|
message.success(t('common.delSuccess'))
|
||||||
|
// 刷新列表
|
||||||
|
await getList()
|
||||||
|
} catch {}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 导出按钮操作 */
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
await exportList(xGrid, '${table.classComment}.xls')
|
try {
|
||||||
|
// 导出的二次确认
|
||||||
|
await message.exportConfirm()
|
||||||
|
// 发起导出
|
||||||
|
exportLoading.value = true
|
||||||
|
const data = await ${simpleClassName}Api.export${simpleClassName}(queryParams)
|
||||||
|
download.excel(data, '${table.classComment}.xls')
|
||||||
|
} catch {
|
||||||
|
} finally {
|
||||||
|
exportLoading.value = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 修改操作
|
/** 初始化 **/
|
||||||
const handleUpdate = async (rowId: number) => {
|
onMounted(() => {
|
||||||
setDialogTile('update')
|
getList()
|
||||||
// 设置数据
|
})
|
||||||
const res = await ${simpleClassName}Api.get${simpleClassName}Api(rowId)
|
|
||||||
unref(formRef)?.setValues(res)
|
|
||||||
modelLoading.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 详情操作
|
|
||||||
const handleDetail = async (rowId: number) => {
|
|
||||||
setDialogTile('detail')
|
|
||||||
const res = await ${simpleClassName}Api.get${simpleClassName}Api(rowId)
|
|
||||||
detailData.value = res
|
|
||||||
modelLoading.value = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// 删除操作
|
|
||||||
const handleDelete = async (rowId: number) => {
|
|
||||||
await deleteData(xGrid, rowId)
|
|
||||||
}
|
|
||||||
|
|
||||||
// 提交按钮
|
|
||||||
const submitForm = async () => {
|
|
||||||
const elForm = unref(formRef)?.getElFormRef()
|
|
||||||
if (!elForm) return
|
|
||||||
elForm.validate(async (valid) => {
|
|
||||||
if (valid) {
|
|
||||||
actionLoading.value = true
|
|
||||||
// 提交请求
|
|
||||||
try {
|
|
||||||
const data = unref(formRef)?.formModel as ${simpleClassName}Api.${simpleClassName}VO
|
|
||||||
if (actionType.value === 'create') {
|
|
||||||
await ${simpleClassName}Api.create${simpleClassName}Api(data)
|
|
||||||
message.success(t('common.createSuccess'))
|
|
||||||
} else {
|
|
||||||
await ${simpleClassName}Api.update${simpleClassName}Api(data)
|
|
||||||
message.success(t('common.updateSuccess'))
|
|
||||||
}
|
|
||||||
modelVisible.value = false
|
|
||||||
} finally {
|
|
||||||
actionLoading.value = false
|
|
||||||
// 刷新列表
|
|
||||||
await getList(xGrid)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
@ -0,0 +1,45 @@
|
|||||||
|
import request from '@/config/axios'
|
||||||
|
|
||||||
|
export interface ${simpleClassName}VO {
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.createOperation || $column.updateOperation)
|
||||||
|
#if(${column.javaType.toLowerCase()} == "long" || ${column.javaType.toLowerCase()} == "integer" || ${column.javaType.toLowerCase()} == "double" || ${column.javaType.toLowerCase()} == "bigdecimal")
|
||||||
|
${column.javaField}: number
|
||||||
|
#elseif(${column.javaType.toLowerCase()} == "date" || ${column.javaType.toLowerCase()} == "localdatetime")
|
||||||
|
${column.javaField}: Date
|
||||||
|
#else
|
||||||
|
${column.javaField}: ${column.javaType.toLowerCase()}
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询${table.classComment}列表
|
||||||
|
export const get${simpleClassName}Page = async (params: ${simpleClassName}PageReqVO) => {
|
||||||
|
return await request.get({ url: '${baseURL}/page', params })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 查询${table.classComment}详情
|
||||||
|
export const get${simpleClassName} = async (id: number) => {
|
||||||
|
return await request.get({ url: '${baseURL}/get?id=' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 新增${table.classComment}
|
||||||
|
export const create${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||||
|
return await request.post({ url: '${baseURL}/create', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 修改${table.classComment}
|
||||||
|
export const update${simpleClassName} = async (data: ${simpleClassName}VO) => {
|
||||||
|
return await request.put({ url: '${baseURL}/update', data })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 删除${table.classComment}
|
||||||
|
export const delete${simpleClassName} = async (id: number) => {
|
||||||
|
return await request.delete({ url: '${baseURL}/delete?id=' + id })
|
||||||
|
}
|
||||||
|
|
||||||
|
// 导出${table.classComment} Excel
|
||||||
|
export const export${simpleClassName}Api = async (params) => {
|
||||||
|
return await request.download({ url: '${baseURL}/export-excel', params })
|
||||||
|
}
|
@ -0,0 +1,129 @@
|
|||||||
|
import type { CrudSchema } from '@/hooks/web/useCrudSchemas'
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if ($column.listOperationResult && $column.htmlType == "datetime")
|
||||||
|
import { dateFormatter } from '@/utils/formatTime'
|
||||||
|
#break
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
|
||||||
|
// 表单校验
|
||||||
|
export const rules = reactive({
|
||||||
|
#foreach ($column in $columns)
|
||||||
|
#if (($column.createOperation || $column.updateOperation) && !$column.nullable && !${column.primaryKey})## 创建或者更新操作 && 要求非空 && 非主键
|
||||||
|
#set($comment=$column.columnComment)
|
||||||
|
$column.javaField: [required],
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
})
|
||||||
|
|
||||||
|
// CrudSchema https://doc.iocoder.cn/vue3/crud-schema/
|
||||||
|
const crudSchemas = reactive<CrudSchema[]>([
|
||||||
|
#foreach($column in $columns)
|
||||||
|
#if ($column.listOperation || $column.listOperationResult || $column.createOperation || $column.updateOperation)
|
||||||
|
#set ($dictType = $column.dictType)
|
||||||
|
#set ($javaField = $column.javaField)
|
||||||
|
#set ($javaType = $column.javaType)
|
||||||
|
{
|
||||||
|
label: '${column.columnComment}',
|
||||||
|
field: '${column.javaField}',
|
||||||
|
## ========= 字典部分 =========
|
||||||
|
#if ("" != $dictType)## 有数据字典
|
||||||
|
dictType: DICT_TYPE.$dictType.toUpperCase(),
|
||||||
|
#if ($javaType == "Integer" || $javaType == "Long" || $javaType == "Byte" || $javaType == "Short")
|
||||||
|
dictClass: 'number',
|
||||||
|
#elseif ($javaType == "String")
|
||||||
|
dictClass: 'string',
|
||||||
|
#elseif ($javaType == "Boolean")
|
||||||
|
dictClass: 'boolean',
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
## ========= Table 表格部分 =========
|
||||||
|
#if (!$column.listOperationResult)
|
||||||
|
isTable: false,
|
||||||
|
#else
|
||||||
|
#if ($column.htmlType == "datetime")
|
||||||
|
formatter: dateFormatter,
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
## ========= Search 表格部分 =========
|
||||||
|
#if ($column.listOperation)
|
||||||
|
isSearch: true,
|
||||||
|
#if ($column.htmlType == "datetime")
|
||||||
|
search: {
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
valueFormat: 'YYYY-MM-DD HH:mm:ss',
|
||||||
|
type: 'daterange',
|
||||||
|
defaultTime: [new Date('1 00:00:00'), new Date('1 23:59:59')]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
## ========= Form 表单部分 =========
|
||||||
|
#if ((!$column.createOperation && !$column.updateOperation) || $column.primaryKey)
|
||||||
|
isForm: false,
|
||||||
|
#else
|
||||||
|
#if($column.htmlType == "imageUpload")## 图片上传
|
||||||
|
form: {
|
||||||
|
component: 'UploadImg'
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "fileUpload")## 文件上传
|
||||||
|
form: {
|
||||||
|
component: 'UploadFile'
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "editor")## 文本编辑器
|
||||||
|
form: {
|
||||||
|
component: 'Editor',
|
||||||
|
componentProps: {
|
||||||
|
valueHtml: '',
|
||||||
|
height: 200
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "select")## 下拉框
|
||||||
|
form: {
|
||||||
|
component: 'SelectV2'
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "checkbox")## 多选框
|
||||||
|
form: {
|
||||||
|
component: 'Checkbox'
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "radio")## 单选框
|
||||||
|
form: {
|
||||||
|
component: 'Radio'
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "datetime")## 时间框
|
||||||
|
form: {
|
||||||
|
component: 'DatePicker',
|
||||||
|
componentProps: {
|
||||||
|
type: 'datetime',
|
||||||
|
valueFormat: 'x'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#elseif($column.htmlType == "textarea")## 文本框
|
||||||
|
form: {
|
||||||
|
component: 'Input',
|
||||||
|
componentProps: {
|
||||||
|
type: 'textarea',
|
||||||
|
rows: 4
|
||||||
|
},
|
||||||
|
colProps: {
|
||||||
|
span: 24
|
||||||
|
}
|
||||||
|
},
|
||||||
|
#elseif(${javaType.toLowerCase()} == "long" || ${javaType.toLowerCase()} == "integer")## 文本框
|
||||||
|
form: {
|
||||||
|
component: 'InputNumber',
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
},
|
||||||
|
#end
|
||||||
|
#end
|
||||||
|
{
|
||||||
|
label: '操作',
|
||||||
|
field: 'action',
|
||||||
|
isForm: false
|
||||||
|
}
|
||||||
|
])
|
||||||
|
export const { allSchemas } = useCrudSchemas(crudSchemas)
|
@ -0,0 +1,65 @@
|
|||||||
|
<template>
|
||||||
|
<Dialog :title="dialogTitle" v-model="dialogVisible">
|
||||||
|
<Form ref="formRef" :schema="allSchemas.formSchema" :rules="rules" v-loading="formLoading" />
|
||||||
|
<template #footer>
|
||||||
|
<el-button @click="submitForm" type="primary" :disabled="formLoading">确 定</el-button>
|
||||||
|
<el-button @click="dialogVisible = false">取 消</el-button>
|
||||||
|
</template>
|
||||||
|
</Dialog>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
|
||||||
|
import { rules, allSchemas } from './${classNameVar}.data'
|
||||||
|
const { t } = useI18n() // 国际化
|
||||||
|
const message = useMessage() // 消息弹窗
|
||||||
|
|
||||||
|
const dialogVisible = ref(false) // 弹窗的是否展示
|
||||||
|
const dialogTitle = ref('') // 弹窗的标题
|
||||||
|
const formLoading = ref(false) // 表单的加载中:1)修改时的数据加载;2)提交的按钮禁用
|
||||||
|
const formType = ref('') // 表单的类型:create - 新增;update - 修改
|
||||||
|
const formRef = ref() // 表单 Ref
|
||||||
|
|
||||||
|
/** 打开弹窗 */
|
||||||
|
const open = async (type: string, id?: number) => {
|
||||||
|
dialogVisible.value = true
|
||||||
|
dialogTitle.value = t('action.' + type)
|
||||||
|
formType.value = type
|
||||||
|
// 修改时,设置数据
|
||||||
|
if (id) {
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = await ${simpleClassName}Api.get${simpleClassName}(id)
|
||||||
|
formRef.value.setValues(data)
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
defineExpose({ open }) // 提供 open 方法,用于打开弹窗
|
||||||
|
|
||||||
|
/** 提交表单 */
|
||||||
|
const emit = defineEmits(['success']) // 定义 success 事件,用于操作成功后的回调
|
||||||
|
const submitForm = async () => {
|
||||||
|
// 校验表单
|
||||||
|
if (!formRef) return
|
||||||
|
const valid = await formRef.value.getElFormRef().validate()
|
||||||
|
if (!valid) return
|
||||||
|
// 提交请求
|
||||||
|
formLoading.value = true
|
||||||
|
try {
|
||||||
|
const data = formRef.value.formModel as ${simpleClassName}Api.${simpleClassName}VO
|
||||||
|
if (formType.value === 'create') {
|
||||||
|
await ${simpleClassName}Api.create${simpleClassName}(data)
|
||||||
|
message.success(t('common.createSuccess'))
|
||||||
|
} else {
|
||||||
|
await ${simpleClassName}Api.update${simpleClassName}(data)
|
||||||
|
message.success(t('common.updateSuccess'))
|
||||||
|
}
|
||||||
|
dialogVisible.value = false
|
||||||
|
// 发送操作成功的事件
|
||||||
|
emit('success')
|
||||||
|
} finally {
|
||||||
|
formLoading.value = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<!-- 搜索工作栏 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<Search :schema="allSchemas.searchSchema" @search="setSearchParams" @reset="setSearchParams">
|
||||||
|
<!-- 新增等操作按钮 -->
|
||||||
|
<template #actionMore>
|
||||||
|
<el-button
|
||||||
|
type="primary"
|
||||||
|
plain
|
||||||
|
@click="openForm('create')"
|
||||||
|
v-hasPermi="['${permissionPrefix}:create']"
|
||||||
|
>
|
||||||
|
<Icon icon="ep:plus" class="mr-5px" /> 新增
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</Search>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 列表 -->
|
||||||
|
<ContentWrap>
|
||||||
|
<Table
|
||||||
|
:columns="allSchemas.tableColumns"
|
||||||
|
:data="tableObject.tableList"
|
||||||
|
:loading="tableObject.loading"
|
||||||
|
:pagination="{
|
||||||
|
total: tableObject.total
|
||||||
|
}"
|
||||||
|
v-model:pageSize="tableObject.pageSize"
|
||||||
|
v-model:currentPage="tableObject.currentPage"
|
||||||
|
>
|
||||||
|
<template #action="{ row }">
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="primary"
|
||||||
|
@click="openForm('update', row.id)"
|
||||||
|
v-hasPermi="['${permissionPrefix}:update']"
|
||||||
|
>
|
||||||
|
编辑
|
||||||
|
</el-button>
|
||||||
|
<el-button
|
||||||
|
link
|
||||||
|
type="danger"
|
||||||
|
v-hasPermi="['${permissionPrefix}:delete']"
|
||||||
|
@click="handleDelete(row.id)"
|
||||||
|
>
|
||||||
|
删除
|
||||||
|
</el-button>
|
||||||
|
</template>
|
||||||
|
</Table>
|
||||||
|
</ContentWrap>
|
||||||
|
|
||||||
|
<!-- 表单弹窗:添加/修改 -->
|
||||||
|
<${simpleClassName}Form ref="formRef" @success="getList" />
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts" name="${table.className}">
|
||||||
|
import { allSchemas } from './${classNameVar}.data'
|
||||||
|
import * as ${simpleClassName}Api from '@/api/${table.moduleName}/${classNameVar}'
|
||||||
|
import ${simpleClassName}Form from './${simpleClassName}Form.vue'
|
||||||
|
|
||||||
|
// tableObject:表格的属性对象,可获得分页大小、条数等属性
|
||||||
|
// tableMethods:表格的操作对象,可进行获得分页、删除记录等操作
|
||||||
|
// 详细可见:https://doc.iocoder.cn/vue3/crud-schema/
|
||||||
|
const { tableObject, tableMethods } = useTable({
|
||||||
|
getListApi: ${simpleClassName}Api.get${simpleClassName}Page, // 分页接口
|
||||||
|
delListApi: ${simpleClassName}Api.delete${simpleClassName} // 删除接口
|
||||||
|
})
|
||||||
|
// 获得表格的各种操作
|
||||||
|
const { getList, setSearchParams } = tableMethods
|
||||||
|
|
||||||
|
/** 添加/修改操作 */
|
||||||
|
const formRef = ref()
|
||||||
|
const openForm = (type: string, id?: number) => {
|
||||||
|
formRef.value.open(type, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 删除按钮操作 */
|
||||||
|
const handleDelete = (id: number) => {
|
||||||
|
tableMethods.delList(id, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/** 初始化 **/
|
||||||
|
onMounted(() => {
|
||||||
|
getList()
|
||||||
|
})
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user