mirror of
https://gitee.com/dromara/RuoYi-Vue-Plus.git
synced 2026-04-18 08:13:16 +08:00
update 重构 增强代码生成器各项功能
update 自动类型判断可根据不同数据库精确识别 对应的java类型 update 优化java字段名与数据库名不匹配则增加别名注解 update 增加 是否导出 是否状态切换 是否组合唯一校验 是否排序调整 和树结构相关字段等功能选择 update 优化自定义路径导出 导出全部代码 update 删除无用主子表相关代码
This commit is contained in:
@@ -45,6 +45,56 @@ public interface GenConstants {
|
||||
*/
|
||||
String PARENT_MENU_NAME = "parentMenuName";
|
||||
|
||||
/**
|
||||
* 是否启用导出能力
|
||||
*/
|
||||
String ENABLE_EXPORT = "enableExport";
|
||||
|
||||
/**
|
||||
* 是否启用状态切换能力
|
||||
*/
|
||||
String ENABLE_STATUS = "enableStatus";
|
||||
|
||||
/**
|
||||
* 状态字段
|
||||
*/
|
||||
String STATUS_FIELD = "statusField";
|
||||
|
||||
/**
|
||||
* 是否启用组合唯一校验
|
||||
*/
|
||||
String ENABLE_UNIQUE = "enableUnique";
|
||||
|
||||
/**
|
||||
* 组合唯一字段
|
||||
*/
|
||||
String UNIQUE_FIELDS = "uniqueFields";
|
||||
|
||||
/**
|
||||
* 是否启用排序调整能力
|
||||
*/
|
||||
String ENABLE_SORT = "enableSort";
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
String SORT_FIELD = "sortField";
|
||||
|
||||
/**
|
||||
* 树根节点值
|
||||
*/
|
||||
String TREE_ROOT_VALUE = "treeRootValue";
|
||||
|
||||
/**
|
||||
* 树祖级字段
|
||||
*/
|
||||
String TREE_ANCESTORS = "treeAncestors";
|
||||
|
||||
/**
|
||||
* 树排序字段
|
||||
*/
|
||||
String TREE_ORDER_FIELD = "treeOrderField";
|
||||
|
||||
/**
|
||||
* 数据库字符串类型
|
||||
*/
|
||||
@@ -128,6 +178,16 @@ public interface GenConstants {
|
||||
*/
|
||||
String HTML_DATETIME = "datetime";
|
||||
|
||||
/**
|
||||
* 开关控件
|
||||
*/
|
||||
String HTML_SWITCH = "switch";
|
||||
|
||||
/**
|
||||
* 数字输入控件
|
||||
*/
|
||||
String HTML_INPUT_NUMBER = "inputNumber";
|
||||
|
||||
/**
|
||||
* 图片上传控件
|
||||
*/
|
||||
@@ -168,6 +228,11 @@ public interface GenConstants {
|
||||
*/
|
||||
String TYPE_BIGDECIMAL = "BigDecimal";
|
||||
|
||||
/**
|
||||
* 布尔类型
|
||||
*/
|
||||
String TYPE_BOOLEAN = "Boolean";
|
||||
|
||||
/**
|
||||
* 时间类型
|
||||
*/
|
||||
|
||||
@@ -55,19 +55,17 @@ public class GenController extends BaseController {
|
||||
* 修改代码生成业务
|
||||
*
|
||||
* @param tableId 表ID
|
||||
* @return 表、字段与可选业务表信息
|
||||
* @return 表与字段信息
|
||||
*/
|
||||
@RepeatSubmit()
|
||||
@SaCheckPermission("tool:gen:query")
|
||||
@GetMapping(value = "/{tableId}")
|
||||
public R<Map<String, Object>> getInfo(@PathVariable Long tableId) {
|
||||
GenTable table = genTableService.selectGenTableById(tableId);
|
||||
List<GenTable> tables = genTableService.selectGenTableAll();
|
||||
List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId);
|
||||
Map<String, Object> map = new HashMap<>(3);
|
||||
Map<String, Object> map = new HashMap<>(2);
|
||||
map.put("info", table);
|
||||
map.put("rows", list);
|
||||
map.put("tables", tables);
|
||||
return R.ok(map);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,16 +51,6 @@ public class GenTable extends BaseEntity {
|
||||
@NotBlank(message = "表描述不能为空")
|
||||
private String tableComment;
|
||||
|
||||
/**
|
||||
* 关联父表的表名
|
||||
*/
|
||||
private String subTableName;
|
||||
|
||||
/**
|
||||
* 本表关联父表的外键名
|
||||
*/
|
||||
private String subTableFkName;
|
||||
|
||||
/**
|
||||
* 实体类名称(首字母大写)
|
||||
*/
|
||||
@@ -68,7 +58,7 @@ public class GenTable extends BaseEntity {
|
||||
private String className;
|
||||
|
||||
/**
|
||||
* 使用的模板(crud单表操作 tree树表操作 sub主子表操作)
|
||||
* 使用的模板(crud单表操作 tree树表操作)
|
||||
*/
|
||||
private String tplCategory;
|
||||
|
||||
@@ -172,6 +162,66 @@ public class GenTable extends BaseEntity {
|
||||
@TableField(exist = false)
|
||||
private String parentMenuName;
|
||||
|
||||
/**
|
||||
* 是否启用导出
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean enableExport;
|
||||
|
||||
/**
|
||||
* 是否启用状态切换
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean enableStatus;
|
||||
|
||||
/**
|
||||
* 状态字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String statusField;
|
||||
|
||||
/**
|
||||
* 是否启用组合唯一校验
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean enableUnique;
|
||||
|
||||
/**
|
||||
* 组合唯一字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private List<String> uniqueFields;
|
||||
|
||||
/**
|
||||
* 是否启用排序调整
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private Boolean enableSort;
|
||||
|
||||
/**
|
||||
* 排序字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String sortField;
|
||||
|
||||
/**
|
||||
* 树根节点值
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String treeRootValue;
|
||||
|
||||
/**
|
||||
* 树祖级字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String treeAncestorsField;
|
||||
|
||||
/**
|
||||
* 树排序字段
|
||||
*/
|
||||
@TableField(exist = false)
|
||||
private String treeOrderField;
|
||||
|
||||
/**
|
||||
* 请求参数
|
||||
*/
|
||||
|
||||
@@ -10,6 +10,7 @@ import lombok.EqualsAndHashCode;
|
||||
import org.apache.ibatis.type.JdbcType;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
import org.dromara.common.mybatis.core.domain.BaseEntity;
|
||||
import org.dromara.gen.constant.GenConstants;
|
||||
|
||||
/**
|
||||
* 代码生成业务字段表 gen_table_column
|
||||
@@ -307,6 +308,31 @@ public class GenTableColumn extends BaseEntity {
|
||||
return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark");
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前列是否需要显式声明 MP 字段映射。
|
||||
*
|
||||
* @return 字段名与下划线列名不一致时返回 {@code true}
|
||||
*/
|
||||
public boolean isNeedTableField() {
|
||||
if (StringUtils.isAnyBlank(this.columnName, this.javaField)) {
|
||||
return false;
|
||||
}
|
||||
return !StringUtils.equalsIgnoreCase(this.columnName, StringUtils.toUnderScoreCase(this.javaField));
|
||||
}
|
||||
|
||||
/**
|
||||
* 判断当前列是否属于字典控件列。
|
||||
*
|
||||
* @return 仅当已配置字典类型且显示类型支持字典时返回 {@code true}
|
||||
*/
|
||||
public boolean isDictColumn() {
|
||||
return StringUtils.isNotBlank(this.dictType) && StringUtils.equalsAny(this.htmlType,
|
||||
GenConstants.HTML_SELECT,
|
||||
GenConstants.HTML_RADIO,
|
||||
GenConstants.HTML_CHECKBOX,
|
||||
GenConstants.HTML_SWITCH);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从字段注释中解析字典读转换表达式。
|
||||
*
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.dromara.gen.service;
|
||||
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.date.LocalDateTimeUtil;
|
||||
import cn.hutool.core.io.IoUtil;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
@@ -220,17 +221,6 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
}).toList();
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询所有表信息
|
||||
*
|
||||
* @return 表信息集合
|
||||
*/
|
||||
@Override
|
||||
public List<GenTable> selectGenTableAll() {
|
||||
return fillTableColumns(baseMapper.selectList(new LambdaQueryWrapper<GenTable>()
|
||||
.orderByAsc(GenTable::getTableId)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 修改业务
|
||||
*
|
||||
@@ -239,6 +229,7 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Override
|
||||
public void updateGenTable(GenTable genTable) {
|
||||
normalizeColumnOptions(genTable.getColumns());
|
||||
String options = JsonUtils.toJsonString(genTable.getParams());
|
||||
genTable.setOptions(options);
|
||||
int row = baseMapper.updateById(genTable);
|
||||
@@ -372,16 +363,13 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
List<PathNamedTemplate> templates = TemplateEngineUtils.getTemplateList(table.getTplCategory(), table.getDataName());
|
||||
for (PathNamedTemplate template : templates) {
|
||||
String pathName = template.getPathName();
|
||||
// 渲染模板
|
||||
if (!StringUtils.containsAny(pathName, "sql.vm", "api.ts.vm", "types.ts.vm", "index.vue.vm", "index-tree.vue.vm")) {
|
||||
// 渲染模板
|
||||
try {
|
||||
String render = template.render(context);
|
||||
String path = getGenPath(table, pathName);
|
||||
FileUtils.writeUtf8String(render, path);
|
||||
} catch (Exception e) {
|
||||
throw new ServiceException("渲染模板失败,表名:" + table.getTableName());
|
||||
}
|
||||
try {
|
||||
String render = template.render(context);
|
||||
String path = getGenPath(table, pathName);
|
||||
FileUtils.writeUtf8String(render, path);
|
||||
} catch (Exception e) {
|
||||
log.error("渲染模板失败,表名:{},模板:{}", table.getTableName(), pathName, e);
|
||||
throw new ServiceException("渲染模板失败,表名:" + table.getTableName() + ",模板:" + pathName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -426,6 +414,7 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
saveColumns.add(column);
|
||||
});
|
||||
if (CollUtil.isNotEmpty(saveColumns)) {
|
||||
normalizeColumnOptions(saveColumns);
|
||||
genTableColumnMapper.insertOrUpdateBatch(saveColumns);
|
||||
}
|
||||
List<GenTableColumn> delColumns = StreamUtils.filter(tableColumns, column -> !dbTableColumnNames.contains(column.getColumnName()));
|
||||
@@ -506,6 +495,7 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
*/
|
||||
@Override
|
||||
public void validateEdit(GenTable genTable) {
|
||||
validateOptionColumns(genTable);
|
||||
if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) {
|
||||
String options = JsonUtils.toJsonString(genTable.getParams());
|
||||
Dict paramsObj = JsonUtils.parseMap(options);
|
||||
@@ -519,6 +509,52 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
}
|
||||
}
|
||||
|
||||
private void validateOptionColumns(GenTable genTable) {
|
||||
Map<String, Object> params = genTable.getParams();
|
||||
if (CollUtil.isEmpty(params) || CollUtil.isEmpty(genTable.getColumns())) {
|
||||
return;
|
||||
}
|
||||
Set<String> validFields = new HashSet<>();
|
||||
genTable.getColumns().forEach(column -> {
|
||||
validFields.add(column.getColumnName());
|
||||
validFields.add(column.getJavaField());
|
||||
});
|
||||
validateOptionField(validFields, params.get(GenConstants.STATUS_FIELD), "状态字段");
|
||||
validateOptionField(validFields, params.get(GenConstants.SORT_FIELD), "排序字段");
|
||||
validateOptionField(validFields, params.get(GenConstants.TREE_ANCESTORS), "树祖级字段");
|
||||
validateOptionField(validFields, params.get(GenConstants.TREE_ORDER_FIELD), "树排序字段");
|
||||
Object uniqueFields = params.get(GenConstants.UNIQUE_FIELDS);
|
||||
if (uniqueFields instanceof Collection<?> collection) {
|
||||
for (Object field : collection) {
|
||||
validateOptionField(validFields, field, "组合唯一字段");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void validateOptionField(Set<String> validFields, Object field, String label) {
|
||||
if (ObjectUtil.isNull(field)) {
|
||||
return;
|
||||
}
|
||||
String fieldValue = Convert.toStr(field);
|
||||
if (StringUtils.isBlank(fieldValue)) {
|
||||
return;
|
||||
}
|
||||
if (!validFields.contains(fieldValue)) {
|
||||
throw new ServiceException(label + "不存在,请刷新字段后重试");
|
||||
}
|
||||
}
|
||||
|
||||
private void normalizeColumnOptions(List<GenTableColumn> columns) {
|
||||
if (CollUtil.isEmpty(columns)) {
|
||||
return;
|
||||
}
|
||||
for (GenTableColumn column : columns) {
|
||||
if (!column.isDictColumn()) {
|
||||
column.setDictType(StringUtils.EMPTY);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 查询业务表并补齐其列信息。
|
||||
*
|
||||
@@ -588,12 +624,32 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
String treeName = paramsObj.getStr(GenConstants.TREE_NAME);
|
||||
Long parentMenuId = paramsObj.getLong(GenConstants.PARENT_MENU_ID);
|
||||
String parentMenuName = paramsObj.getStr(GenConstants.PARENT_MENU_NAME);
|
||||
Boolean enableExport = Convert.toBool(paramsObj.get(GenConstants.ENABLE_EXPORT), true);
|
||||
Boolean enableStatus = Convert.toBool(paramsObj.get(GenConstants.ENABLE_STATUS), false);
|
||||
String statusField = paramsObj.getStr(GenConstants.STATUS_FIELD);
|
||||
Boolean enableUnique = Convert.toBool(paramsObj.get(GenConstants.ENABLE_UNIQUE), false);
|
||||
List<String> uniqueFields = Convert.toList(String.class, paramsObj.get(GenConstants.UNIQUE_FIELDS));
|
||||
Boolean enableSort = Convert.toBool(paramsObj.get(GenConstants.ENABLE_SORT), false);
|
||||
String sortField = paramsObj.getStr(GenConstants.SORT_FIELD);
|
||||
String treeRootValue = paramsObj.getStr(GenConstants.TREE_ROOT_VALUE);
|
||||
String treeAncestorsField = paramsObj.getStr(GenConstants.TREE_ANCESTORS);
|
||||
String treeOrderField = paramsObj.getStr(GenConstants.TREE_ORDER_FIELD);
|
||||
|
||||
genTable.setTreeCode(treeCode);
|
||||
genTable.setTreeParentCode(treeParentCode);
|
||||
genTable.setTreeName(treeName);
|
||||
genTable.setParentMenuId(parentMenuId);
|
||||
genTable.setParentMenuName(parentMenuName);
|
||||
genTable.setEnableExport(enableExport);
|
||||
genTable.setEnableStatus(enableStatus);
|
||||
genTable.setStatusField(statusField);
|
||||
genTable.setEnableUnique(enableUnique);
|
||||
genTable.setUniqueFields(uniqueFields);
|
||||
genTable.setEnableSort(enableSort);
|
||||
genTable.setSortField(sortField);
|
||||
genTable.setTreeRootValue(treeRootValue);
|
||||
genTable.setTreeAncestorsField(treeAncestorsField);
|
||||
genTable.setTreeOrderField(treeOrderField);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -605,11 +661,12 @@ public class GenTableServiceImpl implements IGenTableService {
|
||||
* @return 生成地址
|
||||
*/
|
||||
public static String getGenPath(GenTable table, String template) {
|
||||
String relativePath = StringUtils.replace(TemplateEngineUtils.getFileName(template, table), "/", File.separator);
|
||||
String genPath = table.getGenPath();
|
||||
if (StringUtils.equals(genPath, "/")) {
|
||||
return System.getProperty("user.dir") + File.separator + "src" + File.separator + TemplateEngineUtils.getFileName(template, table);
|
||||
return System.getProperty("user.dir") + File.separator + "src" + File.separator + relativePath;
|
||||
}
|
||||
return genPath + File.separator + TemplateEngineUtils.getFileName(template, table);
|
||||
return genPath + File.separator + relativePath;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,13 +50,6 @@ public interface IGenTableService {
|
||||
*/
|
||||
List<GenTable> selectDbTableListByNames(String[] tableNames, String dataName);
|
||||
|
||||
/**
|
||||
* 查询所有表信息
|
||||
*
|
||||
* @return 表信息集合
|
||||
*/
|
||||
List<GenTable> selectGenTableAll();
|
||||
|
||||
/**
|
||||
* 查询业务信息
|
||||
*
|
||||
|
||||
@@ -45,9 +45,11 @@ public class GenUtils {
|
||||
* @param table 所属业务表对象
|
||||
*/
|
||||
public static void initColumnField(GenTableColumn column, GenTable table) {
|
||||
String dataType = getDbType(column.getColumnType());
|
||||
String dataType = getDbType(column.getColumnType()).toLowerCase();
|
||||
// 统一转小写 避免有些数据库默认大写问题 如果需要特别书写方式 请在实体类增加注解标注别名
|
||||
String columnName = column.getColumnName().toLowerCase();
|
||||
Integer columnLength = getColumnLength(column.getColumnType());
|
||||
Integer columnScale = getColumnScale(column.getColumnType());
|
||||
column.setTableId(table.getTableId());
|
||||
column.setCreateTime(null);
|
||||
column.setUpdateTime(null);
|
||||
@@ -59,17 +61,18 @@ public class GenUtils {
|
||||
|
||||
if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) {
|
||||
// 字符串长度超过500设置为文本域
|
||||
Integer columnLength = getColumnLength(column.getColumnType());
|
||||
String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT;
|
||||
if (isBooleanColumn(dataType, columnLength, columnScale, columnName)) {
|
||||
column.setJavaType(GenConstants.TYPE_BOOLEAN);
|
||||
htmlType = GenConstants.HTML_SWITCH;
|
||||
}
|
||||
column.setHtmlType(htmlType);
|
||||
} else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) {
|
||||
column.setJavaType(GenConstants.TYPE_DATE);
|
||||
column.setHtmlType(GenConstants.HTML_DATETIME);
|
||||
} else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) {
|
||||
column.setHtmlType(GenConstants.HTML_INPUT);
|
||||
// 数据库的数字字段与java不匹配 且很多数据库的数字字段很模糊 例如oracle只有number没有细分
|
||||
// 所以默认数字类型全为Long可在界面上自行编辑想要的类型 有什么特殊需求也可以在这里特殊处理
|
||||
column.setJavaType(GenConstants.TYPE_LONG);
|
||||
column.setJavaType(resolveNumberJavaType(dataType, columnLength, columnScale, columnName));
|
||||
column.setHtmlType(GenConstants.TYPE_BOOLEAN.equals(column.getJavaType()) ? GenConstants.HTML_SWITCH : GenConstants.HTML_INPUT_NUMBER);
|
||||
}
|
||||
|
||||
// BO对象 默认插入勾选
|
||||
@@ -93,29 +96,102 @@ public class GenUtils {
|
||||
if (StringUtils.endsWithIgnoreCase(columnName, "name")) {
|
||||
column.setQueryType(GenConstants.QUERY_LIKE);
|
||||
}
|
||||
if (GenConstants.HTML_DATETIME.equals(column.getHtmlType()) && column.isQuery()) {
|
||||
column.setQueryType(GenConstants.QUERY_BETWEEN);
|
||||
}
|
||||
// 状态字段设置单选框
|
||||
if (isSwitchColumn(columnName) || GenConstants.TYPE_BOOLEAN.equals(column.getJavaType())) {
|
||||
column.setHtmlType(GenConstants.HTML_SWITCH);
|
||||
}
|
||||
// 状态字段设置单选框/开关
|
||||
if (StringUtils.endsWithIgnoreCase(columnName, "status")) {
|
||||
column.setHtmlType(GenConstants.HTML_RADIO);
|
||||
column.setHtmlType(GenConstants.TYPE_BOOLEAN.equals(column.getJavaType()) ? GenConstants.HTML_SWITCH : GenConstants.HTML_RADIO);
|
||||
}
|
||||
// 类型&性别字段设置下拉框
|
||||
else if (StringUtils.endsWithIgnoreCase(columnName, "type")
|
||||
|| StringUtils.endsWithIgnoreCase(columnName, "sex")) {
|
||||
column.setHtmlType(GenConstants.HTML_SELECT);
|
||||
}
|
||||
// 排序字段设置数字输入控件
|
||||
else if (isSortColumn(columnName)) {
|
||||
column.setHtmlType(GenConstants.HTML_INPUT_NUMBER);
|
||||
}
|
||||
// 图片字段设置图片上传控件
|
||||
else if (StringUtils.endsWithIgnoreCase(columnName, "image")) {
|
||||
else if (StringUtils.endsWithAny(columnName, "image", "avatar", "logo", "picture")) {
|
||||
column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD);
|
||||
}
|
||||
// 文件字段设置文件上传控件
|
||||
else if (StringUtils.endsWithIgnoreCase(columnName, "file")) {
|
||||
else if (StringUtils.endsWithAny(columnName, "file", "attachment")) {
|
||||
column.setHtmlType(GenConstants.HTML_FILE_UPLOAD);
|
||||
}
|
||||
// 备注描述类字段设置文本域
|
||||
else if (StringUtils.endsWithAny(columnName, "remark", "description", "desc", "note")) {
|
||||
column.setHtmlType(GenConstants.HTML_TEXTAREA);
|
||||
}
|
||||
// 内容字段设置富文本控件
|
||||
else if (StringUtils.endsWithIgnoreCase(columnName, "content")) {
|
||||
else if (StringUtils.endsWithAny(columnName, "content", "html", "body")) {
|
||||
column.setHtmlType(GenConstants.HTML_EDITOR);
|
||||
}
|
||||
}
|
||||
|
||||
private static String resolveNumberJavaType(String dataType, Integer columnLength, Integer columnScale, String columnName) {
|
||||
if (isBooleanColumn(dataType, columnLength, columnScale, columnName)) {
|
||||
return GenConstants.TYPE_BOOLEAN;
|
||||
}
|
||||
if (arraysContains(new String[]{"decimal", "numeric", "money", "smallmoney"}, dataType)) {
|
||||
return columnScale > 0 ? GenConstants.TYPE_BIGDECIMAL : resolveIntegerJavaType(columnLength);
|
||||
}
|
||||
if (arraysContains(new String[]{"float", "float4", "float8", "double", "real", "double precision"}, dataType)) {
|
||||
return GenConstants.TYPE_DOUBLE;
|
||||
}
|
||||
if (arraysContains(new String[]{"bigint", "int8", "bigserial"}, dataType)) {
|
||||
return GenConstants.TYPE_LONG;
|
||||
}
|
||||
if (arraysContains(new String[]{"smallint", "mediumint", "int", "int2", "int4", "integer", "smallserial", "serial"}, dataType)) {
|
||||
return GenConstants.TYPE_INTEGER;
|
||||
}
|
||||
if (StringUtils.equals(dataType, "number")) {
|
||||
if (columnScale > 0) {
|
||||
return GenConstants.TYPE_BIGDECIMAL;
|
||||
}
|
||||
return resolveIntegerJavaType(columnLength);
|
||||
}
|
||||
return GenConstants.TYPE_LONG;
|
||||
}
|
||||
|
||||
private static String resolveIntegerJavaType(Integer columnLength) {
|
||||
if (columnLength > 0 && columnLength <= 9) {
|
||||
return GenConstants.TYPE_INTEGER;
|
||||
}
|
||||
return GenConstants.TYPE_LONG;
|
||||
}
|
||||
|
||||
private static boolean isBooleanColumn(String dataType, Integer columnLength, Integer columnScale, String columnName) {
|
||||
if (columnScale > 0) {
|
||||
return false;
|
||||
}
|
||||
if (StringUtils.equalsAny(dataType, "bit", "boolean", "bool")) {
|
||||
return true;
|
||||
}
|
||||
if (StringUtils.equalsAny(dataType, "tinyint", "number", "numeric", "decimal", "char", "nchar")
|
||||
&& columnLength == 1 && isSwitchColumn(columnName)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private static boolean isSwitchColumn(String columnName) {
|
||||
return StringUtils.endsWithAny(columnName, "status", "flag", "enabled", "disabled", "available", "visible")
|
||||
|| columnName.startsWith("is_")
|
||||
|| columnName.startsWith("has_")
|
||||
|| columnName.startsWith("enable_")
|
||||
|| columnName.startsWith("disable_");
|
||||
}
|
||||
|
||||
private static boolean isSortColumn(String columnName) {
|
||||
return StringUtils.endsWithAny(columnName, "sort", "order_num", "order", "rank", "seq", "sequence");
|
||||
}
|
||||
|
||||
/**
|
||||
* 校验数组是否包含指定值
|
||||
*
|
||||
@@ -219,14 +295,30 @@ public class GenUtils {
|
||||
*/
|
||||
public static Integer getColumnLength(String columnType) {
|
||||
if (StringUtils.indexOf(columnType, "(") > 0) {
|
||||
String length = StringUtils.substringBetween(columnType, "(", ")");
|
||||
String length = StringUtils.substringBetween(columnType, "(", ")").trim();
|
||||
// 处理 decimal(10,2) 这类带精度的类型,只取长度部分
|
||||
if (length.contains(",")) {
|
||||
length = StringUtils.substringBefore(length, ",");
|
||||
length = StringUtils.substringBefore(length, ",").trim();
|
||||
}
|
||||
return Integer.valueOf(length);
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取字段精度
|
||||
*
|
||||
* @param columnType 列类型
|
||||
* @return 字段精度,未声明精度时返回 0
|
||||
*/
|
||||
public static Integer getColumnScale(String columnType) {
|
||||
if (StringUtils.indexOf(columnType, "(") > 0) {
|
||||
String length = StringUtils.substringBetween(columnType, "(", ")").trim();
|
||||
if (length.contains(",")) {
|
||||
return Integer.valueOf(StringUtils.substringAfter(length, ",").trim());
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.dromara.gen.util;
|
||||
import cn.hutool.core.collection.CollUtil;
|
||||
import cn.hutool.core.convert.Convert;
|
||||
import cn.hutool.core.lang.Dict;
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import cn.hutool.extra.template.TemplateEngine;
|
||||
import cn.hutool.extra.template.TemplateUtil;
|
||||
import lombok.AccessLevel;
|
||||
@@ -108,6 +109,22 @@ public class TemplateEngineUtils {
|
||||
Dict paramsObj = JsonUtils.parseMap(options);
|
||||
String parentMenuId = getParentMenuId(paramsObj);
|
||||
context.put("parentMenuId", parentMenuId);
|
||||
boolean enableExport = getBooleanOption(paramsObj, GenConstants.ENABLE_EXPORT, true);
|
||||
boolean enableStatus = getBooleanOption(paramsObj, GenConstants.ENABLE_STATUS, false);
|
||||
boolean enableUnique = getBooleanOption(paramsObj, GenConstants.ENABLE_UNIQUE, false);
|
||||
boolean enableSort = getBooleanOption(paramsObj, GenConstants.ENABLE_SORT, false);
|
||||
GenTableColumn statusColumn = getColumn(genTable, paramsObj.getStr(GenConstants.STATUS_FIELD));
|
||||
GenTableColumn sortColumn = getColumn(genTable, paramsObj.getStr(GenConstants.SORT_FIELD));
|
||||
List<GenTableColumn> uniqueColumns = getColumns(genTable, paramsObj.get(GenConstants.UNIQUE_FIELDS));
|
||||
context.put("enableExport", enableExport);
|
||||
context.put("enableStatus", enableStatus && ObjectUtil.isNotNull(statusColumn));
|
||||
context.put("statusColumn", statusColumn);
|
||||
context.put("statusField", ObjectUtil.isNotNull(statusColumn) ? statusColumn.getJavaField() : StringUtils.EMPTY);
|
||||
context.put("enableUnique", enableUnique && CollUtil.isNotEmpty(uniqueColumns));
|
||||
context.put("uniqueColumns", uniqueColumns);
|
||||
context.put("enableSort", enableSort && ObjectUtil.isNotNull(sortColumn));
|
||||
context.put("sortColumn", sortColumn);
|
||||
context.put("sortField", ObjectUtil.isNotNull(sortColumn) ? sortColumn.getJavaField() : StringUtils.EMPTY);
|
||||
|
||||
// 向树形模板上下文写入树字段相关变量
|
||||
if (GenConstants.TPL_TREE.equals(tplCategory)) {
|
||||
@@ -128,10 +145,21 @@ public class TemplateEngineUtils {
|
||||
String treeCode = getTreeCode(paramsObj);
|
||||
String treeParentCode = getTreeParentCode(paramsObj);
|
||||
String treeName = getTreeName(paramsObj);
|
||||
GenTableColumn treeParentColumn = getColumn(genTable, paramsObj.getStr(GenConstants.TREE_PARENT_CODE));
|
||||
GenTableColumn treeAncestorsColumn = getColumn(genTable, paramsObj.getStr(GenConstants.TREE_ANCESTORS));
|
||||
GenTableColumn treeOrderColumn = getColumn(genTable, paramsObj.getStr(GenConstants.TREE_ORDER_FIELD));
|
||||
String treeRootValue = getTreeRootValue(paramsObj, treeParentColumn);
|
||||
|
||||
context.put("treeCode", treeCode);
|
||||
context.put("treeParentCode", treeParentCode);
|
||||
context.put("treeName", treeName);
|
||||
context.put("treeParentColumn", treeParentColumn);
|
||||
context.put("treeAncestorsField", ObjectUtil.isNotNull(treeAncestorsColumn) ? treeAncestorsColumn.getJavaField() : StringUtils.EMPTY);
|
||||
context.put("treeOrderField", ObjectUtil.isNotNull(treeOrderColumn) ? treeOrderColumn.getJavaField() : StringUtils.EMPTY);
|
||||
context.put("treeOrderColumn", treeOrderColumn);
|
||||
context.put("treeRootValue", treeRootValue);
|
||||
context.put("treeRootValueJavaLiteral", getJavaLiteral(treeParentColumn, treeRootValue));
|
||||
context.put("treeRootValueTsLiteral", getTsLiteral(treeParentColumn, treeRootValue));
|
||||
String expandTreeName = paramsObj.getStr(GenConstants.TREE_NAME);
|
||||
int expandColumn = 0;
|
||||
for (GenTableColumn column : genTable.getColumns()) {
|
||||
@@ -307,7 +335,7 @@ public class TemplateEngineUtils {
|
||||
for (GenTableColumn column : columns) {
|
||||
if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny(
|
||||
column.getHtmlType(),
|
||||
new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) {
|
||||
new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX, GenConstants.HTML_SWITCH })) {
|
||||
dicts.add("'" + column.getDictType() + "'");
|
||||
}
|
||||
}
|
||||
@@ -376,4 +404,81 @@ public class TemplateEngineUtils {
|
||||
}
|
||||
return StringUtils.EMPTY;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取树根节点值。
|
||||
*
|
||||
* @param paramsObj 其他选项
|
||||
* @param treeParentColumn 父节点字段
|
||||
* @return 树根节点值
|
||||
*/
|
||||
public static String getTreeRootValue(Dict paramsObj, GenTableColumn treeParentColumn) {
|
||||
String defaultValue = "0";
|
||||
if (ObjectUtil.isNotNull(treeParentColumn) && StringUtils.equals(treeParentColumn.getJavaType(), GenConstants.TYPE_STRING)) {
|
||||
defaultValue = "0";
|
||||
}
|
||||
if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_ROOT_VALUE)) {
|
||||
return StringUtils.blankToDefault(paramsObj.getStr(GenConstants.TREE_ROOT_VALUE), defaultValue);
|
||||
}
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
private static boolean getBooleanOption(Dict paramsObj, String key, boolean defaultValue) {
|
||||
if (CollUtil.isEmpty(paramsObj) || !paramsObj.containsKey(key)) {
|
||||
return defaultValue;
|
||||
}
|
||||
return Convert.toBool(paramsObj.get(key), defaultValue);
|
||||
}
|
||||
|
||||
private static GenTableColumn getColumn(GenTable genTable, String field) {
|
||||
if (StringUtils.isBlank(field) || CollUtil.isEmpty(genTable.getColumns())) {
|
||||
return null;
|
||||
}
|
||||
for (GenTableColumn column : genTable.getColumns()) {
|
||||
if (StringUtils.equalsAny(field, column.getColumnName(), column.getJavaField())) {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static List<GenTableColumn> getColumns(GenTable genTable, Object fieldValues) {
|
||||
List<String> fields = new ArrayList<>();
|
||||
if (fieldValues instanceof Collection<?> collection) {
|
||||
collection.stream().map(Convert::toStr).forEach(fields::add);
|
||||
} else if (ObjectUtil.isNotNull(fieldValues)) {
|
||||
fields.addAll(StringUtils.str2List(Convert.toStr(fieldValues), StringUtils.SEPARATOR, true, true));
|
||||
}
|
||||
List<GenTableColumn> columns = new ArrayList<>();
|
||||
for (String field : fields) {
|
||||
GenTableColumn column = getColumn(genTable, field);
|
||||
if (ObjectUtil.isNotNull(column)) {
|
||||
columns.add(column);
|
||||
}
|
||||
}
|
||||
return columns;
|
||||
}
|
||||
|
||||
private static String getJavaLiteral(GenTableColumn column, String value) {
|
||||
if (ObjectUtil.isNull(column) || StringUtils.isBlank(value)) {
|
||||
return "null";
|
||||
}
|
||||
if (StringUtils.equals(column.getJavaType(), GenConstants.TYPE_LONG)) {
|
||||
return value + "L";
|
||||
}
|
||||
if (StringUtils.equalsAny(column.getJavaType(), GenConstants.TYPE_INTEGER, GenConstants.TYPE_DOUBLE, GenConstants.TYPE_BIGDECIMAL)) {
|
||||
return value;
|
||||
}
|
||||
return "\"" + value + "\"";
|
||||
}
|
||||
|
||||
private static String getTsLiteral(GenTableColumn column, String value) {
|
||||
if (ObjectUtil.isNull(column) || StringUtils.isBlank(value)) {
|
||||
return "undefined";
|
||||
}
|
||||
if (StringUtils.equalsAny(column.getJavaType(), GenConstants.TYPE_LONG, GenConstants.TYPE_INTEGER, GenConstants.TYPE_DOUBLE, GenConstants.TYPE_BIGDECIMAL)) {
|
||||
return value;
|
||||
}
|
||||
return "'" + value + "'";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package ${packageName}.controller;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.RequiredArgsConstructor;
|
||||
#if($enableExport)
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
#end
|
||||
import jakarta.validation.constraints.*;
|
||||
import cn.dev33.satoken.annotation.SaCheckPermission;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
@@ -16,7 +18,9 @@ import org.dromara.common.core.domain.R;
|
||||
import org.dromara.common.core.validate.AddGroup;
|
||||
import org.dromara.common.core.validate.EditGroup;
|
||||
import org.dromara.common.log.enums.BusinessType;
|
||||
#if($enableExport)
|
||||
import org.dromara.common.excel.utils.ExcelUtil;
|
||||
#end
|
||||
import ${packageName}.domain.vo.${ClassName}Vo;
|
||||
import ${packageName}.domain.bo.${ClassName}Bo;
|
||||
import ${packageName}.service.I${ClassName}Service;
|
||||
@@ -58,6 +62,7 @@ public class ${ClassName}Controller extends BaseController {
|
||||
/**
|
||||
* 导出${functionName}列表
|
||||
*/
|
||||
#if($enableExport)
|
||||
@SaCheckPermission("${permissionPrefix}:export")
|
||||
@Log(title = "${functionName}", businessType = BusinessType.EXPORT)
|
||||
@PostMapping("/export")
|
||||
@@ -65,6 +70,7 @@ public class ${ClassName}Controller extends BaseController {
|
||||
List<${ClassName}Vo> list = ${className}Service.queryList(bo);
|
||||
ExcelUtil.exportExcel(list, "${functionName}", ${ClassName}Vo.class, response);
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* 获取${functionName}详细信息
|
||||
@@ -86,6 +92,11 @@ public class ${ClassName}Controller extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PostMapping()
|
||||
public R<Void> add(@Validated(AddGroup.class) @RequestBody ${ClassName}Bo bo) {
|
||||
#if($enableUnique)
|
||||
if (!${className}Service.checkUnique(bo)) {
|
||||
return R.fail("新增${functionName}失败,组合唯一字段已存在");
|
||||
}
|
||||
#end
|
||||
return toAjax(${className}Service.insertByBo(bo));
|
||||
}
|
||||
|
||||
@@ -97,9 +108,38 @@ public class ${ClassName}Controller extends BaseController {
|
||||
@RepeatSubmit()
|
||||
@PutMapping()
|
||||
public R<Void> edit(@Validated(EditGroup.class) @RequestBody ${ClassName}Bo bo) {
|
||||
#if($enableUnique)
|
||||
if (!${className}Service.checkUnique(bo)) {
|
||||
return R.fail("修改${functionName}失败,组合唯一字段已存在");
|
||||
}
|
||||
#end
|
||||
return toAjax(${className}Service.updateByBo(bo));
|
||||
}
|
||||
|
||||
#if($enableStatus)
|
||||
/**
|
||||
* 修改${functionName}状态
|
||||
*/
|
||||
@SaCheckPermission("${permissionPrefix}:edit")
|
||||
@Log(title = "${functionName}", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/changeStatus")
|
||||
public R<Void> changeStatus(@RequestBody ${ClassName}Bo bo) {
|
||||
return toAjax(${className}Service.updateStatus(bo.get${pkColumn.capJavaField}(), bo.get${statusColumn.capJavaField}()));
|
||||
}
|
||||
#end
|
||||
|
||||
#if($enableSort)
|
||||
/**
|
||||
* 调整${functionName}排序
|
||||
*/
|
||||
@SaCheckPermission("${permissionPrefix}:edit")
|
||||
@Log(title = "${functionName}", businessType = BusinessType.UPDATE)
|
||||
@PutMapping("/updateSort")
|
||||
public R<Void> updateSort(@RequestBody ${ClassName}Bo bo) {
|
||||
return toAjax(${className}Service.updateSort(bo.get${pkColumn.capJavaField}(), bo.get${sortColumn.capJavaField}()));
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* 删除${functionName}
|
||||
*
|
||||
|
||||
@@ -38,6 +38,8 @@ public class ${ClassName} extends ${Entity} {
|
||||
#end
|
||||
#if($column.isPk==1)
|
||||
@TableId(value = "$column.columnName")
|
||||
#elseif($column.needTableField)
|
||||
@TableField(value = "$column.columnName")
|
||||
#end
|
||||
private $column.javaType $column.javaField;
|
||||
|
||||
|
||||
@@ -45,6 +45,16 @@ public interface I${ClassName}Service {
|
||||
*/
|
||||
List<${ClassName}Vo> queryList(${ClassName}Bo bo);
|
||||
|
||||
#if($enableUnique)
|
||||
/**
|
||||
* 校验${functionName}是否满足组合唯一约束
|
||||
*
|
||||
* @param bo ${functionName}
|
||||
* @return 是否唯一
|
||||
*/
|
||||
boolean checkUnique(${ClassName}Bo bo);
|
||||
#end
|
||||
|
||||
/**
|
||||
* 新增${functionName}
|
||||
*
|
||||
@@ -61,6 +71,28 @@ public interface I${ClassName}Service {
|
||||
*/
|
||||
Boolean updateByBo(${ClassName}Bo bo);
|
||||
|
||||
#if($enableStatus)
|
||||
/**
|
||||
* 修改${functionName}状态
|
||||
*
|
||||
* @param ${pkColumn.javaField} 主键
|
||||
* @param status 状态值
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateStatus(${pkColumn.javaType} ${pkColumn.javaField}, ${statusColumn.javaType} status);
|
||||
#end
|
||||
|
||||
#if($enableSort)
|
||||
/**
|
||||
* 调整${functionName}排序
|
||||
*
|
||||
* @param ${pkColumn.javaField} 主键
|
||||
* @param sortValue 排序值
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
Boolean updateSort(${pkColumn.javaType} ${pkColumn.javaField}, ${sortColumn.javaType} sortValue);
|
||||
#end
|
||||
|
||||
/**
|
||||
* 校验并批量删除${functionName}信息
|
||||
*
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ${packageName}.service.impl;
|
||||
|
||||
import cn.hutool.core.util.ObjectUtil;
|
||||
import org.dromara.common.core.utils.MapstructUtils;
|
||||
import org.dromara.common.core.utils.StringUtils;
|
||||
#if($table.crud)
|
||||
@@ -7,6 +8,9 @@ import org.dromara.common.core.domain.PageResult;
|
||||
import org.dromara.common.mybatis.core.page.PageQuery;
|
||||
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
|
||||
#end
|
||||
#if($enableStatus || $enableSort)
|
||||
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
|
||||
#end
|
||||
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
|
||||
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
@@ -17,7 +21,11 @@ import ${packageName}.domain.vo.${ClassName}Vo;
|
||||
import ${packageName}.domain.${ClassName};
|
||||
import ${packageName}.mapper.${ClassName}Mapper;
|
||||
import ${packageName}.service.I${ClassName}Service;
|
||||
#if($table.tree)
|
||||
import org.dromara.common.core.exception.ServiceException;
|
||||
#end
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Collection;
|
||||
@@ -35,6 +43,19 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
|
||||
private final ${ClassName}Mapper baseMapper;
|
||||
|
||||
#set($TreeParentCap = "")
|
||||
#if("" != $treeParentCode)
|
||||
#set($TreeParentCap = $treeParentCode.substring(0,1).toUpperCase() + $treeParentCode.substring(1))
|
||||
#end
|
||||
#set($TreeAncestorsCap = "")
|
||||
#if("" != $treeAncestorsField)
|
||||
#set($TreeAncestorsCap = $treeAncestorsField.substring(0,1).toUpperCase() + $treeAncestorsField.substring(1))
|
||||
#end
|
||||
#set($TreeOrderCap = "")
|
||||
#if("" != $treeOrderField)
|
||||
#set($TreeOrderCap = $treeOrderField.substring(0,1).toUpperCase() + $treeOrderField.substring(1))
|
||||
#end
|
||||
|
||||
/**
|
||||
* 查询${functionName}
|
||||
*
|
||||
@@ -42,7 +63,7 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
* @return ${functionName}
|
||||
*/
|
||||
@Override
|
||||
public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){
|
||||
public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}) {
|
||||
return baseMapper.selectVoById(${pkColumn.javaField});
|
||||
}
|
||||
|
||||
@@ -74,7 +95,37 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
return baseMapper.selectVoList(lqw);
|
||||
}
|
||||
|
||||
#if($enableUnique)
|
||||
/**
|
||||
* 校验${functionName}是否满足组合唯一约束
|
||||
*
|
||||
* @param bo ${functionName}
|
||||
* @return 是否唯一
|
||||
*/
|
||||
@Override
|
||||
public boolean checkUnique(${ClassName}Bo bo) {
|
||||
boolean hasUniqueValue = true;
|
||||
#foreach($column in $uniqueColumns)
|
||||
#if($column.javaType == 'String')
|
||||
hasUniqueValue = hasUniqueValue && StringUtils.isNotBlank(bo.get${column.capJavaField}());
|
||||
#else
|
||||
hasUniqueValue = hasUniqueValue && bo.get${column.capJavaField}() != null;
|
||||
#end
|
||||
#end
|
||||
if (!hasUniqueValue) {
|
||||
return true;
|
||||
}
|
||||
LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery();
|
||||
#foreach($column in $uniqueColumns)
|
||||
lqw.eq(${ClassName}::get${column.capJavaField}, bo.get${column.capJavaField}());
|
||||
#end
|
||||
lqw.ne(bo.get${pkColumn.capJavaField}() != null, ${ClassName}::get${pkColumn.capJavaField}, bo.get${pkColumn.capJavaField}());
|
||||
return !baseMapper.exists(lqw);
|
||||
}
|
||||
#end
|
||||
|
||||
private LambdaQueryWrapper<${ClassName}> buildQueryWrapper(${ClassName}Bo bo) {
|
||||
#set($hasBetween = false)
|
||||
#foreach ($column in $columns)
|
||||
#if($column.query && $column.queryType == 'BETWEEN')
|
||||
#set($hasBetween = true)
|
||||
@@ -87,10 +138,8 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
#foreach($column in $columns)
|
||||
#if($column.query)
|
||||
#set($queryType=$column.queryType)
|
||||
#set($javaField=$column.javaField)
|
||||
#set($javaType=$column.javaType)
|
||||
#set($columnName=$column.columnName)
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#set($AttrName=$column.capJavaField)
|
||||
#set($mpMethod=$column.queryType.toLowerCase())
|
||||
#if($queryType != 'BETWEEN')
|
||||
#if($javaType == 'String')
|
||||
@@ -101,14 +150,22 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
lqw.$mpMethod($condition, ${ClassName}::get$AttrName, bo.get$AttrName());
|
||||
#else
|
||||
lqw.between(params.get("begin$AttrName") != null && params.get("end$AttrName") != null,
|
||||
${ClassName}::get$AttrName ,params.get("begin$AttrName"), params.get("end$AttrName"));
|
||||
${ClassName}::get$AttrName, params.get("begin$AttrName"), params.get("end$AttrName"));
|
||||
#end
|
||||
#end
|
||||
#set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)})
|
||||
#if($column.isPk==1)
|
||||
lqw.orderByAsc(${ClassName}::get$AttrName);
|
||||
#end
|
||||
#if($table.tree && "" != $treeAncestorsField)
|
||||
lqw.orderByAsc(${ClassName}::get${TreeAncestorsCap});
|
||||
#end
|
||||
#if($table.tree && "" != $treeParentCode)
|
||||
lqw.orderByAsc(${ClassName}::get${TreeParentCap});
|
||||
#end
|
||||
#if($table.tree && "" != $treeOrderField)
|
||||
lqw.orderByAsc(${ClassName}::get${TreeOrderCap});
|
||||
#elseif($enableSort)
|
||||
lqw.orderByAsc(${ClassName}::get${sortColumn.capJavaField});
|
||||
#end
|
||||
lqw.orderByAsc(${ClassName}::get${pkColumn.capJavaField});
|
||||
return lqw;
|
||||
}
|
||||
|
||||
@@ -121,11 +178,13 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
@Override
|
||||
public Boolean insertByBo(${ClassName}Bo bo) {
|
||||
${ClassName} add = MapstructUtils.convert(bo, ${ClassName}.class);
|
||||
#if($table.tree)
|
||||
fillTreeMetaBeforeSave(add, false);
|
||||
#end
|
||||
validEntityBeforeSave(add);
|
||||
boolean flag = baseMapper.insert(add) > 0;
|
||||
#set($pk=$pkColumn.javaField.substring(0,1).toUpperCase() + ${pkColumn.javaField.substring(1)})
|
||||
if (flag) {
|
||||
bo.set$pk(add.get$pk());
|
||||
bo.set${pkColumn.capJavaField}(add.get${pkColumn.capJavaField}());
|
||||
}
|
||||
return flag;
|
||||
}
|
||||
@@ -139,17 +198,133 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
@Override
|
||||
public Boolean updateByBo(${ClassName}Bo bo) {
|
||||
${ClassName} update = MapstructUtils.convert(bo, ${ClassName}.class);
|
||||
#if($table.tree)
|
||||
fillTreeMetaBeforeSave(update, true);
|
||||
#end
|
||||
validEntityBeforeSave(update);
|
||||
return baseMapper.updateById(update) > 0;
|
||||
}
|
||||
|
||||
#if($enableStatus)
|
||||
/**
|
||||
* 修改${functionName}状态
|
||||
*
|
||||
* @param ${pkColumn.javaField} 主键
|
||||
* @param status 状态值
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateStatus(${pkColumn.javaType} ${pkColumn.javaField}, ${statusColumn.javaType} status) {
|
||||
return baseMapper.update(null, new LambdaUpdateWrapper<${ClassName}>()
|
||||
.set(${ClassName}::get${statusColumn.capJavaField}, status)
|
||||
.eq(${ClassName}::get${pkColumn.capJavaField}, ${pkColumn.javaField})) > 0;
|
||||
}
|
||||
#end
|
||||
|
||||
#if($enableSort)
|
||||
/**
|
||||
* 调整${functionName}排序
|
||||
*
|
||||
* @param ${pkColumn.javaField} 主键
|
||||
* @param sortValue 排序值
|
||||
* @return 是否修改成功
|
||||
*/
|
||||
@Override
|
||||
public Boolean updateSort(${pkColumn.javaType} ${pkColumn.javaField}, ${sortColumn.javaType} sortValue) {
|
||||
return baseMapper.update(null, new LambdaUpdateWrapper<${ClassName}>()
|
||||
.set(${ClassName}::get${sortColumn.capJavaField}, sortValue)
|
||||
.eq(${ClassName}::get${pkColumn.capJavaField}, ${pkColumn.javaField})) > 0;
|
||||
}
|
||||
#end
|
||||
|
||||
/**
|
||||
* 保存前的数据校验
|
||||
*/
|
||||
private void validEntityBeforeSave(${ClassName} entity){
|
||||
//TODO 做一些数据校验,如唯一约束
|
||||
private void validEntityBeforeSave(${ClassName} entity) {
|
||||
// 可在此扩展通用业务校验
|
||||
}
|
||||
|
||||
#if($table.tree)
|
||||
private void fillTreeMetaBeforeSave(${ClassName} entity, boolean updateMode) {
|
||||
#if("" != $treeParentCode)
|
||||
if (entity.get${TreeParentCap}() == null) {
|
||||
entity.set${TreeParentCap}(${treeRootValueJavaLiteral});
|
||||
}
|
||||
if (ObjectUtil.equal(entity.get${pkColumn.capJavaField}(), entity.get${TreeParentCap}())) {
|
||||
throw new ServiceException("${functionName}父节点不能选择自身");
|
||||
}
|
||||
#if("" != $treeAncestorsField)
|
||||
${ClassName} parent = null;
|
||||
if (!ObjectUtil.equal(entity.get${TreeParentCap}(), ${treeRootValueJavaLiteral})) {
|
||||
parent = baseMapper.selectById(entity.get${TreeParentCap}());
|
||||
if (ObjectUtil.isNull(parent)) {
|
||||
throw new ServiceException("${functionName}父节点不存在");
|
||||
}
|
||||
}
|
||||
if (updateMode && entity.get${pkColumn.capJavaField}() != null && ObjectUtil.isNotNull(parent)
|
||||
&& containsAncestor(parent.get${TreeAncestorsCap}(), entity.get${pkColumn.capJavaField}())) {
|
||||
throw new ServiceException("不能选择当前节点或其子节点作为父节点");
|
||||
}
|
||||
String newAncestors = resolveAncestors(entity.get${TreeParentCap}(), parent);
|
||||
if (updateMode && entity.get${pkColumn.capJavaField}() != null) {
|
||||
${ClassName} oldEntity = baseMapper.selectById(entity.get${pkColumn.capJavaField}());
|
||||
if (ObjectUtil.isNull(oldEntity)) {
|
||||
throw new ServiceException("${functionName}不存在,无法修改");
|
||||
}
|
||||
String oldAncestors = oldEntity.get${TreeAncestorsCap}();
|
||||
entity.set${TreeAncestorsCap}(newAncestors);
|
||||
if (!StringUtils.equals(oldAncestors, newAncestors)) {
|
||||
updateChildrenAncestors(entity.get${pkColumn.capJavaField}(), newAncestors, oldAncestors);
|
||||
}
|
||||
} else {
|
||||
entity.set${TreeAncestorsCap}(newAncestors);
|
||||
}
|
||||
#end
|
||||
#end
|
||||
}
|
||||
#if("" != $treeAncestorsField)
|
||||
|
||||
private String resolveAncestors(${treeParentColumn.javaType} parentId, ${ClassName} parent) {
|
||||
if (ObjectUtil.equal(parentId, ${treeRootValueJavaLiteral})) {
|
||||
return "${treeRootValue}";
|
||||
}
|
||||
String parentAncestors = parent.get${TreeAncestorsCap}();
|
||||
if (StringUtils.isBlank(parentAncestors)) {
|
||||
return String.valueOf(parentId);
|
||||
}
|
||||
return parentAncestors + StringUtils.SEPARATOR + parentId;
|
||||
}
|
||||
|
||||
private void updateChildrenAncestors(${pkColumn.javaType} currentId, String newAncestors, String oldAncestors) {
|
||||
List<${ClassName}> children = baseMapper.selectList(new LambdaQueryWrapper<${ClassName}>()
|
||||
.select(${ClassName}::get${pkColumn.capJavaField}, ${ClassName}::get${TreeAncestorsCap}()));
|
||||
List<${ClassName}> updateList = new ArrayList<>();
|
||||
for (${ClassName} child : children) {
|
||||
String ancestors = child.get${TreeAncestorsCap}();
|
||||
if (StringUtils.isBlank(ancestors) || !containsAncestor(ancestors, currentId)) {
|
||||
continue;
|
||||
}
|
||||
${ClassName} update = new ${ClassName}();
|
||||
update.set${pkColumn.capJavaField}(child.get${pkColumn.capJavaField}());
|
||||
update.set${TreeAncestorsCap}(StringUtils.replaceOnce(ancestors, oldAncestors, newAncestors));
|
||||
updateList.add(update);
|
||||
}
|
||||
if (!updateList.isEmpty()) {
|
||||
baseMapper.updateBatchById(updateList);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean containsAncestor(String ancestors, ${pkColumn.javaType} nodeId) {
|
||||
for (String item : StringUtils.splitList(ancestors)) {
|
||||
if (StringUtils.equals(item, String.valueOf(nodeId))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
#end
|
||||
#end
|
||||
|
||||
/**
|
||||
* 校验并批量删除${functionName}信息
|
||||
*
|
||||
@@ -159,8 +334,8 @@ public class ${ClassName}ServiceImpl implements I${ClassName}Service {
|
||||
*/
|
||||
@Override
|
||||
public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) {
|
||||
if(isValid){
|
||||
//TODO 做一些业务上的校验,判断是否需要校验
|
||||
if (isValid) {
|
||||
// 可在此扩展删除前业务校验
|
||||
}
|
||||
return baseMapper.deleteByIds(ids) > 0;
|
||||
}
|
||||
|
||||
@@ -52,6 +52,42 @@ export const update${BusinessName} = (data: ${BusinessName}Form) => {
|
||||
});
|
||||
};
|
||||
|
||||
#if($enableStatus)
|
||||
/**
|
||||
* 修改${functionName}状态
|
||||
* @param ${pkColumn.javaField}
|
||||
* @param status
|
||||
*/
|
||||
export const change${BusinessName}Status = (${pkColumn.javaField}: string | number, status: #if($statusColumn.javaType == 'String')string#else number#end) => {
|
||||
return request({
|
||||
url: '/${moduleName}/${businessName}/changeStatus',
|
||||
method: 'put',
|
||||
data: {
|
||||
${pkColumn.javaField},
|
||||
${statusField}: status
|
||||
}
|
||||
});
|
||||
};
|
||||
#end
|
||||
|
||||
#if($enableSort)
|
||||
/**
|
||||
* 调整${functionName}排序
|
||||
* @param ${pkColumn.javaField}
|
||||
* @param sortValue
|
||||
*/
|
||||
export const update${BusinessName}Sort = (${pkColumn.javaField}: string | number, sortValue: #if($sortColumn.javaType == 'String' || $sortColumn.javaType == 'LocalDateTime')string#else number#end) => {
|
||||
return request({
|
||||
url: '/${moduleName}/${businessName}/updateSort',
|
||||
method: 'put',
|
||||
data: {
|
||||
${pkColumn.javaField},
|
||||
${sortField}: sortValue
|
||||
}
|
||||
});
|
||||
};
|
||||
#end
|
||||
|
||||
/**
|
||||
* 删除${functionName}
|
||||
* @param ${pkColumn.javaField}
|
||||
|
||||
@@ -22,12 +22,37 @@
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "inputNumber")
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-input-number v-model="queryParams.${column.javaField}" controls-position="right" />
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
|
||||
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "switch" && "" != $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
|
||||
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "switch")
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
|
||||
#if($column.javaType == "Boolean")
|
||||
<el-option label="是" :value="true" />
|
||||
<el-option label="否" :value="false" />
|
||||
#elseif($column.javaType == "Integer" || $column.javaType == "Long")
|
||||
<el-option label="开启" :value="0" />
|
||||
<el-option label="关闭" :value="1" />
|
||||
#else
|
||||
<el-option label="开启" value="0" />
|
||||
<el-option label="关闭" value="1" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable>
|
||||
@@ -75,6 +100,9 @@
|
||||
<div class="toolbar-actions">
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
|
||||
<el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button>
|
||||
#if($enableExport)
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button>
|
||||
#end
|
||||
<right-toolbar v-model:show-search="showSearch" :search="false" @query-table="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
@@ -104,6 +132,64 @@
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
#if($column.pk)
|
||||
#elseif($enableStatus && $statusField == $javaField)
|
||||
#if($javaField == $firstTreeListField)
|
||||
<el-table-column label="${comment}" prop="${javaField}">
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
#end
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.${javaField}"
|
||||
:active-value="${statusField}ActiveValue"
|
||||
:inactive-value="${statusField}InactiveValue"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($enableSort && $sortField == $javaField)
|
||||
#if($javaField == $firstTreeListField)
|
||||
<el-table-column label="${comment}" prop="${javaField}" width="160">
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="160">
|
||||
#end
|
||||
<template #default="scope">
|
||||
#if($column.javaType == "LocalDateTime")
|
||||
<el-date-picker
|
||||
v-model="scope.row.${javaField}"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择${comment}"
|
||||
@change="handleSortChange(scope.row)"
|
||||
/>
|
||||
#else
|
||||
<el-input-number v-model="scope.row.${javaField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
|
||||
#end
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.htmlType == "switch")
|
||||
#if($javaField == $firstTreeListField)
|
||||
<el-table-column label="${comment}" prop="${javaField}" width="120">
|
||||
#else
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="120">
|
||||
#end
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.${javaField}"
|
||||
#if($column.javaType == "Boolean")
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
#elseif($column.javaType == "Integer" || $column.javaType == "Long")
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
#else
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
#end
|
||||
disabled
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.htmlType == "datetime")
|
||||
#if($javaField == $firstTreeListField)
|
||||
<el-table-column label="${comment}" prop="${javaField}" width="180">
|
||||
@@ -124,7 +210,7 @@
|
||||
<image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.dictType && "" != $column.dictType)
|
||||
#elseif($column.list && $column.dictColumn)
|
||||
#if($javaField == $firstTreeListField)
|
||||
<el-table-column label="${comment}" prop="${javaField}">
|
||||
#else
|
||||
@@ -145,6 +231,35 @@
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#end
|
||||
#if($enableStatus && !$statusColumn.list)
|
||||
<el-table-column label="${statusColumn.columnComment}" align="center" prop="${statusField}">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.${statusField}"
|
||||
:active-value="${statusField}ActiveValue"
|
||||
:inactive-value="${statusField}InactiveValue"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#if($enableSort && !$sortColumn.list)
|
||||
<el-table-column label="${sortColumn.columnComment}" align="center" prop="${sortField}" width="160">
|
||||
<template #default="scope">
|
||||
#if($sortColumn.javaType == "LocalDateTime")
|
||||
<el-date-picker
|
||||
v-model="scope.row.${sortField}"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择${sortColumn.columnComment}"
|
||||
@change="handleSortChange(scope.row)"
|
||||
/>
|
||||
#else
|
||||
<el-input-number v-model="scope.row.${sortField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
|
||||
#end
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
@@ -189,6 +304,10 @@
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "inputNumber")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-input-number v-model="form.${field}" controls-position="right" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<image-upload v-model="form.${field}"/>
|
||||
@@ -259,6 +378,22 @@
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "switch")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-switch
|
||||
v-model="form.${field}"
|
||||
#if($column.javaType == "Boolean")
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
#elseif($column.javaType == "Integer" || $column.javaType == "Long")
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
#else
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
#end
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-date-picker clearable
|
||||
@@ -293,7 +428,19 @@
|
||||
#end
|
||||
#end
|
||||
<script setup name="${BusinessName}" lang="ts">
|
||||
import { add${BusinessName}, del${BusinessName}, get${BusinessName}, list${BusinessName}, update${BusinessName} } from '@/api/${moduleName}/${businessName}';
|
||||
import {
|
||||
add${BusinessName},
|
||||
#if($enableStatus)
|
||||
change${BusinessName}Status,
|
||||
#end
|
||||
del${BusinessName},
|
||||
get${BusinessName},
|
||||
list${BusinessName},
|
||||
#if($enableSort)
|
||||
update${BusinessName}Sort,
|
||||
#end
|
||||
update${BusinessName}
|
||||
} from '@/api/${moduleName}/${businessName}';
|
||||
import { ${BusinessName}Form, ${BusinessName}Query, ${BusinessName}VO } from '@/api/${moduleName}/${businessName}/types';
|
||||
import { useLoading } from '@/hooks/async/useLoading';
|
||||
import { useFormDialog } from '@/hooks/dialog/useFormDialog';
|
||||
@@ -308,20 +455,29 @@ import { useDict } from '@/utils/dict';
|
||||
#end
|
||||
import modal from '@/plugins/modal';
|
||||
import { handleTree } from '@/utils/ruoyi';
|
||||
#if($enableExport)
|
||||
import { download as requestDownload } from '@/utils/request';
|
||||
#end
|
||||
|
||||
#if(${dicts} != '')
|
||||
#set($dictsNoSymbol=$dicts.replace("'", ""))
|
||||
const { ${dictsNoSymbol} } = toRefs<any>(useDict(${dicts}));
|
||||
#end
|
||||
|
||||
#if($enableStatus)
|
||||
const ${statusField}ActiveValue = #if($statusColumn.javaType == "Boolean")true#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")0#else'0'#end;
|
||||
const ${statusField}InactiveValue = #if($statusColumn.javaType == "Boolean")false#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")1#else'1'#end;
|
||||
#end
|
||||
|
||||
type ${BusinessName}Option = {
|
||||
${treeCode}: number;
|
||||
${treeCode}: #if($treeParentColumn.javaType == 'String')string#else number#end;
|
||||
${treeName}: string;
|
||||
children?: ${BusinessName}Option[];
|
||||
};
|
||||
|
||||
const ${businessName}List = ref<${BusinessName}VO[]>([]);
|
||||
const ${businessName}Options = ref<${BusinessName}Option[]>([]);
|
||||
const all${BusinessName}Options = ref<${BusinessName}Option[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const { showSearch } = useSearchToggle();
|
||||
const { loading, setLoading, withLoading } = useLoading();
|
||||
@@ -388,7 +544,7 @@ const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
$column.javaField: [
|
||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
|
||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "switch" || $column.htmlType == "inputNumber")"change"#else"blur"#end }
|
||||
]#if($foreach.count != $columns.size()),#end
|
||||
#end
|
||||
#end
|
||||
@@ -426,12 +582,12 @@ const getList = async () => {
|
||||
};
|
||||
|
||||
/** 查询${functionName}下拉树结构 */
|
||||
const getTreeselect = async () => {
|
||||
const getTreeselect = async (excludeId?: string | number) => {
|
||||
const res = await list${BusinessName}();
|
||||
${businessName}Options.value = [];
|
||||
const data: ${BusinessName}Option = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] };
|
||||
const data: ${BusinessName}Option = { ${treeCode}: ${treeRootValueTsLiteral}, ${treeName}: '顶级节点', children: [] };
|
||||
data.children = handleTree<${BusinessName}Option>(res.data, '${treeCode}', '${treeParentCode}');
|
||||
${businessName}Options.value.push(data);
|
||||
all${BusinessName}Options.value = [data];
|
||||
${businessName}Options.value = excludeId != null ? filterTreeOptions(all${BusinessName}Options.value, excludeId) : all${BusinessName}Options.value;
|
||||
};
|
||||
|
||||
/** 取消按钮 */
|
||||
@@ -468,14 +624,14 @@ const handleAdd = (row?: ${BusinessName}VO) => {
|
||||
if (row != null && row.${treeCode}) {
|
||||
form.value.${treeParentCode} = row.${treeCode};
|
||||
} else {
|
||||
form.value.${treeParentCode} = 0;
|
||||
form.value.${treeParentCode} = ${treeRootValueTsLiteral};
|
||||
}
|
||||
};
|
||||
|
||||
/** 修改按钮操作 */
|
||||
const handleUpdate = async (row: ${BusinessName}VO) => {
|
||||
reset();
|
||||
await getTreeselect();
|
||||
await getTreeselect(row.${treeCode});
|
||||
if (row != null) {
|
||||
form.value.${treeParentCode} = row.${treeParentCode};
|
||||
}
|
||||
@@ -520,6 +676,54 @@ const handleDelete = async (row: ${BusinessName}VO) => {
|
||||
modal.msgSuccess('删除成功');
|
||||
};
|
||||
|
||||
const filterTreeOptions = (options: ${BusinessName}Option[], excludeId: string | number): ${BusinessName}Option[] => {
|
||||
return options
|
||||
.filter(item => item.${treeCode} !== excludeId)
|
||||
.map(item => ({
|
||||
...item,
|
||||
children: item.children ? filterTreeOptions(item.children, excludeId) : []
|
||||
}));
|
||||
};
|
||||
|
||||
#if($enableStatus)
|
||||
/** 状态修改 */
|
||||
const handleStatusChange = async (row: ${BusinessName}VO) => {
|
||||
const text = row.${statusField} === ${statusField}ActiveValue ? '启用' : '停用';
|
||||
try {
|
||||
await modal.confirm('确认要"' + text + '"吗?');
|
||||
await change${BusinessName}Status(row.${pkColumn.javaField}, row.${statusField});
|
||||
modal.msgSuccess(text + '成功');
|
||||
} catch (err) {
|
||||
row.${statusField} = row.${statusField} === ${statusField}ActiveValue ? ${statusField}InactiveValue : ${statusField}ActiveValue;
|
||||
}
|
||||
};
|
||||
#end
|
||||
|
||||
#if($enableSort)
|
||||
/** 排序调整 */
|
||||
const handleSortChange = async (row: ${BusinessName}VO) => {
|
||||
try {
|
||||
await update${BusinessName}Sort(row.${pkColumn.javaField}, row.${sortField});
|
||||
modal.msgSuccess('排序更新成功');
|
||||
} catch (err) {
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
#end
|
||||
|
||||
#if($enableExport)
|
||||
/** 导出按钮操作 */
|
||||
const handleExport = () => {
|
||||
requestDownload(
|
||||
'${moduleName}/${businessName}/export',
|
||||
{
|
||||
...queryParams.value
|
||||
},
|
||||
`${businessName}_#[[${new Date().getTime()}]]#.xlsx`
|
||||
);
|
||||
};
|
||||
#end
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
});
|
||||
|
||||
@@ -22,12 +22,37 @@
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "inputNumber")
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-input-number v-model="queryParams.${column.javaField}" controls-position="right" />
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable >
|
||||
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "switch" && "" != $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable >
|
||||
<el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "switch")
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable >
|
||||
#if($column.javaType == "Boolean")
|
||||
<el-option label="是" :value="true" />
|
||||
<el-option label="否" :value="false" />
|
||||
#elseif($column.javaType == "Integer" || $column.javaType == "Long")
|
||||
<el-option label="开启" :value="0" />
|
||||
<el-option label="关闭" :value="1" />
|
||||
#else
|
||||
<el-option label="开启" value="0" />
|
||||
<el-option label="关闭" value="1" />
|
||||
#end
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
#elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType)
|
||||
<el-form-item label="${comment}" prop="${column.javaField}">
|
||||
<el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable >
|
||||
@@ -76,7 +101,9 @@
|
||||
<el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button>
|
||||
<el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button>
|
||||
<el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button>
|
||||
#if($enableExport)
|
||||
<el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button>
|
||||
#end
|
||||
<right-toolbar v-model:show-search="showSearch" :search="false" @query-table="getList"></right-toolbar>
|
||||
</div>
|
||||
</div>
|
||||
@@ -94,6 +121,52 @@
|
||||
#end
|
||||
#if($column.pk)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" v-if="${column.list}" />
|
||||
#elseif($enableStatus && $statusField == $javaField)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.${javaField}"
|
||||
:active-value="${statusField}ActiveValue"
|
||||
:inactive-value="${statusField}InactiveValue"
|
||||
@change="handleStatusChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($enableSort && $sortField == $javaField)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="160">
|
||||
<template #default="scope">
|
||||
#if($column.javaType == "LocalDateTime")
|
||||
<el-date-picker
|
||||
v-model="scope.row.${javaField}"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择${comment}"
|
||||
@change="handleSortChange(scope.row)"
|
||||
/>
|
||||
#else
|
||||
<el-input-number v-model="scope.row.${javaField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
|
||||
#end
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.htmlType == "switch")
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="120">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.${javaField}"
|
||||
#if($column.javaType == "Boolean")
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
#elseif($column.javaType == "Integer" || $column.javaType == "Long")
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
#else
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
#end
|
||||
disabled
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.htmlType == "datetime")
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" width="180">
|
||||
<template #default="scope">
|
||||
@@ -106,7 +179,7 @@
|
||||
<image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#elseif($column.list && $column.dictType && "" != $column.dictType)
|
||||
#elseif($column.list && $column.dictColumn)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}">
|
||||
<template #default="scope">
|
||||
#if($column.htmlType == "checkbox")
|
||||
@@ -119,6 +192,43 @@
|
||||
#elseif($column.list && "" != $javaField)
|
||||
<el-table-column label="${comment}" align="center" prop="${javaField}" />
|
||||
#end
|
||||
#end
|
||||
#if($enableStatus && !$statusColumn.list)
|
||||
<el-table-column label="${statusColumn.columnComment}" align="center" prop="${statusField}">
|
||||
<template #default="scope">
|
||||
<el-switch
|
||||
v-model="scope.row.${statusField}"
|
||||
#if($statusColumn.javaType == "Boolean")
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
#else
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
#end
|
||||
@change="handleStatusChange(scope.row)"
|
||||
/>
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
#if($enableSort && !$sortColumn.list)
|
||||
<el-table-column label="${sortColumn.columnComment}" align="center" prop="${sortField}" width="160">
|
||||
<template #default="scope">
|
||||
#if($sortColumn.javaType == "LocalDateTime")
|
||||
<el-date-picker
|
||||
v-model="scope.row.${sortField}"
|
||||
type="datetime"
|
||||
value-format="YYYY-MM-DD HH:mm:ss"
|
||||
placeholder="选择${sortColumn.columnComment}"
|
||||
@change="handleSortChange(scope.row)"
|
||||
/>
|
||||
#else
|
||||
<el-input-number v-model="scope.row.${sortField}" controls-position="right" :min="0" @change="handleSortChange(scope.row)" />
|
||||
#end
|
||||
</template>
|
||||
</el-table-column>
|
||||
#end
|
||||
<el-table-column label="操作" align="center" class-name="small-padding fixed-width">
|
||||
<template #default="scope">
|
||||
@@ -151,6 +261,10 @@
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-input v-model="form.${field}" placeholder="请输入${comment}" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "inputNumber")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-input-number v-model="form.${field}" controls-position="right" />
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "imageUpload")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<image-upload v-model="form.${field}"/>
|
||||
@@ -221,6 +335,22 @@
|
||||
<el-radio value="1">请选择字典生成</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "switch")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-switch
|
||||
v-model="form.${field}"
|
||||
#if($column.javaType == "Boolean")
|
||||
:active-value="true"
|
||||
:inactive-value="false"
|
||||
#elseif($column.javaType == "Integer" || $column.javaType == "Long")
|
||||
:active-value="0"
|
||||
:inactive-value="1"
|
||||
#else
|
||||
active-value="0"
|
||||
inactive-value="1"
|
||||
#end
|
||||
/>
|
||||
</el-form-item>
|
||||
#elseif($column.htmlType == "datetime")
|
||||
<el-form-item label="${comment}" prop="${field}">
|
||||
<el-date-picker clearable
|
||||
@@ -255,7 +385,19 @@
|
||||
#end
|
||||
#end
|
||||
<script setup name="${BusinessName}" lang="ts">
|
||||
import { add${BusinessName}, del${BusinessName}, get${BusinessName}, list${BusinessName}, update${BusinessName} } from '@/api/${moduleName}/${businessName}';
|
||||
import {
|
||||
add${BusinessName},
|
||||
#if($enableStatus)
|
||||
change${BusinessName}Status,
|
||||
#end
|
||||
del${BusinessName},
|
||||
get${BusinessName},
|
||||
list${BusinessName},
|
||||
#if($enableSort)
|
||||
update${BusinessName}Sort,
|
||||
#end
|
||||
update${BusinessName}
|
||||
} from '@/api/${moduleName}/${businessName}';
|
||||
import { ${BusinessName}Form, ${BusinessName}Query, ${BusinessName}VO } from '@/api/${moduleName}/${businessName}/types';
|
||||
import { useLoading } from '@/hooks/async/useLoading';
|
||||
import { useFormDialog } from '@/hooks/dialog/useFormDialog';
|
||||
@@ -269,13 +411,20 @@ import { useTableSelection } from '@/hooks/table/useTableSelection';
|
||||
import { useDict } from '@/utils/dict';
|
||||
#end
|
||||
import modal from '@/plugins/modal';
|
||||
#if($enableExport)
|
||||
import { download as requestDownload } from '@/utils/request';
|
||||
#end
|
||||
|
||||
#if(${dicts} != '')
|
||||
#set($dictsNoSymbol=$dicts.replace("'", ""))
|
||||
const { ${dictsNoSymbol} } = toRefs<any>(useDict(${dicts}));
|
||||
#end
|
||||
|
||||
#if($enableStatus)
|
||||
const ${statusField}ActiveValue = #if($statusColumn.javaType == "Boolean")true#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")0#else'0'#end;
|
||||
const ${statusField}InactiveValue = #if($statusColumn.javaType == "Boolean")false#elseif($statusColumn.javaType == "Integer" || $statusColumn.javaType == "Long")1#else'1'#end;
|
||||
#end
|
||||
|
||||
const ${businessName}List = ref<${BusinessName}VO[]>([]);
|
||||
const buttonLoading = ref(false);
|
||||
const { loading, withLoading } = useLoading(true);
|
||||
@@ -339,7 +488,7 @@ const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({
|
||||
#set($comment=$column.columnComment)
|
||||
#end
|
||||
$column.javaField: [
|
||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end }
|
||||
{ required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio" || $column.htmlType == "switch" || $column.htmlType == "inputNumber")"change"#else"blur"#end }
|
||||
]#if($foreach.count != $columns.size()),#end
|
||||
#end
|
||||
#end
|
||||
@@ -457,6 +606,7 @@ const handleDelete = async (row?: ${BusinessName}VO) => {
|
||||
};
|
||||
|
||||
/** 导出按钮操作 */
|
||||
#if($enableExport)
|
||||
const handleExport = () => {
|
||||
requestDownload(
|
||||
'${moduleName}/${businessName}/export',
|
||||
@@ -466,6 +616,33 @@ const handleExport = () => {
|
||||
`${businessName}_#[[${new Date().getTime()}]]#.xlsx`
|
||||
);
|
||||
};
|
||||
#end
|
||||
|
||||
#if($enableStatus)
|
||||
/** 状态修改 */
|
||||
const handleStatusChange = async (row: ${BusinessName}VO) => {
|
||||
const text = row.${statusField} === ${statusField}ActiveValue ? '启用' : '停用';
|
||||
try {
|
||||
await modal.confirm('确认要"' + text + '"吗?');
|
||||
await change${BusinessName}Status(row.${pkColumn.javaField}, row.${statusField});
|
||||
modal.msgSuccess(text + '成功');
|
||||
} catch (err) {
|
||||
row.${statusField} = row.${statusField} === ${statusField}ActiveValue ? ${statusField}InactiveValue : ${statusField}ActiveValue;
|
||||
}
|
||||
};
|
||||
#end
|
||||
|
||||
#if($enableSort)
|
||||
/** 排序调整 */
|
||||
const handleSortChange = async (row: ${BusinessName}VO) => {
|
||||
try {
|
||||
await update${BusinessName}Sort(row.${pkColumn.javaField}, row.${sortField});
|
||||
modal.msgSuccess('排序更新成功');
|
||||
} catch (err) {
|
||||
await getList();
|
||||
}
|
||||
};
|
||||
#end
|
||||
|
||||
onMounted(() => {
|
||||
getList();
|
||||
|
||||
Reference in New Issue
Block a user