This commit is contained in:
kk
2026-07-07 18:01:21 +08:00
commit b259f94d4b
1088 changed files with 121778 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<artifactId>BladeX-Tool</artifactId>
<groupId>org.springblade</groupId>
<version>${revision}</version>
</parent>
<artifactId>blade-starter-develop</artifactId>
<name>${project.artifactId}</name>
<version>${project.parent.version}</version>
<packaging>jar</packaging>
<properties>
<module.name>org.springblade.blade.starter.develop</module.name>
</properties>
<dependencies>
<!--Blade-->
<dependency>
<groupId>org.springblade</groupId>
<artifactId>blade-core-tool</artifactId>
</dependency>
<!--Mybatis-Plus-Generator-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
</dependency>
<!--Beetl-->
<dependency>
<groupId>com.ibeetl</groupId>
<artifactId>beetl</artifactId>
</dependency>
<dependency>
<groupId>org.antlr</groupId>
<artifactId>antlr4-runtime</artifactId>
</dependency>
</dependencies>
</project>
@@ -0,0 +1,109 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.develop;
import org.springblade.develop.constant.DevelopConstant;
import org.springblade.develop.support.BladeCodeGenerator;
/**
* 代码生成器
*
* @author Chill
*/
public class CodeGenerator {
/**
* 代码生成的模块名
*/
public static String CODE_NAME = "应用管理";
/**
* 代码所在服务名
*/
public static String SERVICE_NAME = "blade-system";
/**
* 代码生成的包名
*/
public static String PACKAGE_NAME = "org.springblade.system";
/**
* 前端代码生成风格
*/
public static String CODE_STYLE = DevelopConstant.SABER_NAME;
/**
* 前端代码生成地址
*/
public static String PACKAGE_WEB_DIR = "/Users/chill/Workspaces/product/Saber";
/**
* 需要去掉的表前缀
*/
public static String[] TABLE_PREFIX = {"blade_"};
/**
* 需要生成的表名(两者只能取其一)
*/
public static String[] INCLUDE_TABLES = {"blade_client"};
/**
* 需要排除的表名(两者只能取其一)
*/
public static String[] EXCLUDE_TABLES = {};
/**
* 是否包含基础业务字段
*/
public static Boolean HAS_SUPER_ENTITY = Boolean.TRUE;
/**
* 基础业务字段
*/
public static String[] SUPER_ENTITY_COLUMNS = {"id", "create_time", "create_user", "create_dept", "update_time", "update_user", "status", "is_deleted"};
/**
* 是否包含包装器
*/
public static Boolean HAS_WRAPPER = Boolean.TRUE;
/**
* 是否包含远程调用
*/
public static Boolean HAS_FEIGN = Boolean.FALSE;
/**
* RUN THIS
*/
public static void run() {
BladeCodeGenerator generator = new BladeCodeGenerator();
generator.setCodeName(CODE_NAME);
generator.setServiceName(SERVICE_NAME);
generator.setCodeStyle(CODE_STYLE);
generator.setPackageName(PACKAGE_NAME);
generator.setPackageWebDir(PACKAGE_WEB_DIR);
generator.setTablePrefix(TABLE_PREFIX);
generator.setIncludeTables(INCLUDE_TABLES);
generator.setExcludeTables(EXCLUDE_TABLES);
generator.setHasSuperEntity(HAS_SUPER_ENTITY);
generator.setSuperEntityColumns(SUPER_ENTITY_COLUMNS);
generator.setHasWrapper(HAS_WRAPPER);
generator.setHasFeign(HAS_FEIGN);
generator.run();
}
}
@@ -0,0 +1,95 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.develop.constant;
/**
* 代码生成系统常量.
*
* @author Chill
*/
public interface DevelopConstant {
/**
* 作者信息
*/
String AUTHOR_NAME = "BladeX";
/**
* boot 系统名
*/
String BOOT_NAME = "boot";
/**
* cloud 系统名
*/
String CLOUD_NAME = "cloud";
/**
* sword 系统名
*/
String SWORD_NAME = "sword";
/**
* saber 系统名
*/
String SABER_NAME = "saber";
/**
* saber3 系统名
*/
String SABER3_NAME = "saber3";
/**
* lemon 系统名
*/
String LEMON_NAME = "lemon";
/**
* element 系统名
*/
String ELEMENT_NAME = "element";
/**
* element-plus 系统名
*/
String ELEMENT_PLUS_NAME = "element-plus";
/**
* 单表模式
*/
String TEMPLATE_CRUD = "crud";
/**
* 树表模式
*/
String TEMPLATE_TREE = "tree";
/**
* 主子表模式
*/
String TEMPLATE_SUB = "sub";
/**
* 主模块
*/
String TEMPLATE_MAIN = "main";
}
@@ -0,0 +1,422 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.develop.support;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.toolkit.JdbcUtils;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Mapper;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.stream.Collectors;
import static org.springblade.develop.constant.DevelopConstant.*;
/**
* 代码生成器配置类
*
* @author Chill
*/
@Data
@Slf4j
public class BladeCodeGenerator {
/**
* 代码风格
*/
private String codeStyle = SABER_NAME;
/**
* 代码模块名称
*/
private String codeName;
/**
* 模型编号
*/
private String modelCode;
/**
* 模型实体类
*/
private String modelClass;
/**
* 代码所在服务名
*/
private String serviceName = "blade-service";
/**
* 代码生成的包名
*/
private String packageName = "org.springblade.test";
/**
* 模版类型
*/
private String templateType = TEMPLATE_CRUD;
/**
* 作者信息
*/
private String author;
/**
* 上级菜单主键
*/
private String menuId;
/**
* 子表模型主键
*/
private String subModelId;
/**
* 子表绑定外键
*/
private String subFkId;
/**
* 树主键字段
*/
private String treeId;
/**
* 树父主键字段
*/
private String treePid;
/**
* 树名称字段
*/
private String treeName;
/**
* 代码后端生成的地址
*/
private String packageDir;
/**
* 代码前端生成的地址
*/
private String packageWebDir;
/**
* 需要去掉的表前缀
*/
private String[] tablePrefix = {"blade_"};
/**
* 需要生成的表名(两者只能取其一)
*/
private String[] includeTables = {"blade_test"};
/**
* 需要排除的表名(两者只能取其一)
*/
private String[] excludeTables = {};
/**
* 是否包含基础业务字段
*/
private Boolean hasSuperEntity = Boolean.TRUE;
/**
* 是否包含包装器
*/
private Boolean hasWrapper = Boolean.TRUE;
/**
* 是否包含远程调用
*/
private Boolean hasFeign = Boolean.FALSE;
/**
* 是否包含服务名
*/
private Boolean hasServiceName = Boolean.FALSE;
/**
* 是否包含菜单SQL
*/
private Boolean hasMenuSql = Boolean.TRUE;
/**
* 基础业务字段
*/
private String[] superEntityColumns = {"create_time", "create_user", "create_dept", "update_time", "update_user", "status", "is_deleted"};
/**
* 租户字段
*/
private String tenantColumn = "tenant_id";
/**
* 数据库驱动名
*/
private String driverName;
/**
* 数据库链接地址
*/
private String url;
/**
* 数据库用户名
*/
private String username;
/**
* 数据库密码
*/
private String password;
/**
* 表单设计
*/
private String modelFormOption;
/**
* 数据模型
*/
private Map<String, Object> model;
/**
* 数据原型
*/
private List<Map<String, Object>> prototypes;
/**
* 子数据模型
*/
private Map<String, Object> subModel;
/**
* 子数据原型
*/
private List<Map<String, Object>> subPrototypes;
/**
* 代码生成执行
*/
public void run() {
// 主模块代码生成
getAutoGenerator(getCustomMap(TEMPLATE_MAIN), getCustomFile(TEMPLATE_MAIN)).templateEngine(new BladeTemplateEngine(getOutputDir(), getOutputWebDir())).execute();
// 子模块代码生成
if (Func.equals(templateType, TEMPLATE_SUB) && StringUtil.isNotBlank(subModelId)) {
getAutoGenerator(getCustomMap(TEMPLATE_SUB), getCustomFile(TEMPLATE_SUB)).templateEngine(new BladeTemplateEngine(getOutputDir(), getOutputWebDir())).execute();
}
}
/**
* 设置 customMap
*/
private Map<String, Object> getCustomMap(String generateType) {
List<Map<String, Object>> prototypeList;
String[] split = packageName.split("\\.");
String serviceCode = split[split.length - 1];
Map<String, Object> customMap = new HashMap<>(11);
this.author = StringUtil.isBlank(author) ? AUTHOR_NAME : author;
customMap.put("generateType", generateType);
customMap.put("codeName", codeName);
customMap.put("serviceName", serviceName);
customMap.put("serviceCode", serviceCode);
customMap.put("packageName", packageName);
customMap.put("tenantColumn", tenantColumn);
customMap.put("hasWrapper", hasWrapper);
customMap.put("hasServiceName", hasServiceName);
customMap.put("hasSuperEntity", hasSuperEntity);
customMap.put("hasMenuSql", hasMenuSql);
customMap.put("templateType", templateType);
customMap.put("author", author);
customMap.put("menuId", menuId);
customMap.put("subModelId", subModelId);
customMap.put("subFkId", subFkId);
customMap.put("treeId", treeId);
customMap.put("treePid", treePid);
customMap.put("treeName", treeName);
customMap.put("subFkIdHump", StringUtil.underlineToHump(subFkId));
customMap.put("treeIdHump", StringUtil.underlineToHump(treeId));
customMap.put("treePidHump", StringUtil.underlineToHump(treePid));
customMap.put("modelFormOption", modelFormOption);
if (Func.equals(generateType, TEMPLATE_SUB)) {
prototypeList = subPrototypes;
customMap.put("model", subModel);
customMap.put("prototypes", subPrototypes);
customMap.put("modelCode", subModel.get("modelCode"));
customMap.put("modelClass", subModel.get("modelClass"));
customMap.put("modelTable", subModel.get("modelTable"));
} else {
prototypeList = prototypes;
customMap.put("model", model);
customMap.put("prototypes", prototypes);
customMap.put("subModel", subModel);
customMap.put("subPrototypes", subPrototypes);
customMap.put("modelCode", model.get("modelCode"));
customMap.put("modelClass", model.get("modelClass"));
customMap.put("modelTable", model.get("modelTable"));
}
List<String> propertyImport = prototypeList.stream().filter(prototype -> {
String propertyType = String.valueOf(prototype.get("propertyType"));
return !"String".equals(propertyType) && !"Integer".equals(propertyType) && !"Long".equals(propertyType);
})
.map(prototype -> String.valueOf(prototype.get("propertyEntity")))
.filter(entity -> entity != null && !"null".equals(entity))
.distinct().collect(Collectors.toList());
customMap.put("propertyImport", propertyImport);
return customMap;
}
/**
* 设置 customFile
*/
private Map<String, String> getCustomFile(String type) {
Map<String, String> customFile = new HashMap<>(15);
if (!Func.equals(type, TEMPLATE_SUB)) {
customFile.put("menu.sql", "/templates/sql/menu.sql.btl");
}
customFile.put("entityVO.java", "/templates/api/entityVO.java.btl");
customFile.put("entityDTO.java", "/templates/api/entityDTO.java.btl");
customFile.put("entityExcel.java", "/templates/api/entityExcel.java.btl");
if (hasWrapper) {
customFile.put("wrapper.java", "/templates/api/wrapper.java.btl");
}
if (hasFeign) {
customFile.put("feign.java", "/templates/api/feign.java.btl");
customFile.put("feignclient.java", "/templates/api/feignclient.java.btl");
}
if (Func.isNotBlank(packageWebDir)) {
if (Func.equals(codeStyle, SWORD_NAME)) {
customFile.put("action.js", "/templates/sword/action.js.btl");
customFile.put("model.js", "/templates/sword/model.js.btl");
customFile.put("service.js", "/templates/sword/service.js.btl");
customFile.put("list.js", "/templates/sword/list.js.btl");
customFile.put("add.js", "/templates/sword/add.js.btl");
customFile.put("edit.js", "/templates/sword/edit.js.btl");
customFile.put("view.js", "/templates/sword/view.js.btl");
} else if (Func.equals(codeStyle, SABER_NAME)) {
customFile.put("api.js", "/templates/saber/" + templateType + "/api.js.btl");
customFile.put("option.js", "/templates/saber/" + templateType + "/option.js.btl");
if (!Func.equals(type, TEMPLATE_SUB)) {
customFile.put("crud.vue", "/templates/saber/" + templateType + "/crud.vue.btl");
}
} else if (Func.equals(codeStyle, SABER3_NAME)) {
customFile.put("api.js", "/templates/saber3/" + templateType + "/api.js.btl");
customFile.put("option.js", "/templates/saber3/" + templateType + "/option.js.btl");
if (!Func.equals(type, TEMPLATE_SUB)) {
customFile.put("crud.vue", "/templates/saber3/" + templateType + "/crud.vue.btl");
}
if (Func.isNotEmpty(this.modelFormOption)) {
customFile.put("crud.vue", "/templates/saber3/crud/crud-form.vue.btl");
customFile.put("option.js", "/templates/saber3/crud/option-form.js.btl");
}
} else if (Func.equals(codeStyle, ELEMENT_NAME)) {
customFile.put("api.js", "/templates/element/" + templateType + "/api.js.btl");
customFile.put("option.js", "/templates/element/" + templateType + "/option.js.btl");
if (!Func.equals(type, TEMPLATE_SUB)) {
customFile.put("crud.vue", "/templates/element/" + templateType + "/crud.vue.btl");
} else {
customFile.put("sub.vue", "/templates/element/" + templateType + "/sub.vue.btl");
}
} else if (Func.equals(codeStyle, ELEMENT_PLUS_NAME)) {
customFile.put("api.js", "/templates/element-plus/" + templateType + "/api.js.btl");
customFile.put("option.js", "/templates/element-plus/" + templateType + "/option.js.btl");
if (!Func.equals(type, TEMPLATE_SUB)) {
customFile.put("crud.vue", "/templates/element-plus/" + templateType + "/crud.vue.btl");
} else {
customFile.put("sub.vue", "/templates/element-plus/" + templateType + "/sub.vue.btl");
}
} else if (Func.equals(codeStyle, LEMON_NAME)) {
customFile.put("data.ts", "/templates/lemon/" + templateType + "/data.ts.btl");
customFile.put("Modal.vue", "/templates/lemon/" + templateType + "/Modal.vue.btl");
customFile.put("data.data.ts", "/templates/lemon/" + templateType + "/data.data.ts.btl");
if (!Func.equals(type, TEMPLATE_SUB)) {
customFile.put("index.vue", "/templates/lemon/" + templateType + "/index.vue.btl");
} else {
customFile.put("lemonSub.vue", "/templates/lemon/" + templateType + "/sub.vue.btl");
}
}
}
return customFile;
}
private FastAutoGenerator getAutoGenerator(Map<String, Object> customMap, Map<String, String> customFile) {
Properties props = getProperties();
String url = getJdbcUrl(Func.toStr(this.url, props.getProperty("spring.datasource.url")));
String username = Func.toStr(this.username, props.getProperty("spring.datasource.username"));
String password = Func.toStr(this.password, props.getProperty("spring.datasource.password"));
return FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> builder.author(author).dateType(DateType.TIME_PACK).enableSwagger().outputDir(getOutputDir()).disableOpenDir())
.packageConfig(builder -> builder.parent(packageName).controller("controller").entity("pojo.entity").service("service").serviceImpl("service.impl").mapper("mapper").xml("mapper"))
.strategyConfig(builder -> builder.addTablePrefix(tablePrefix).addInclude(Func.toStrArray(String.valueOf(customMap.get("modelTable")))).addExclude(excludeTables)
.entityBuilder().naming(NamingStrategy.underline_to_camel).columnNaming(NamingStrategy.underline_to_camel).enableLombok().superClass("org.springblade.core.tenant.mp.TenantEntity").formatFileName("%sEntity").addSuperEntityColumns(superEntityColumns).enableFileOverride()
.javaTemplate("/templates/api/entity.java")
.serviceBuilder().superServiceClass("org.springblade.core.mp.base.BaseService").superServiceImplClass("org.springblade.core.mp.base.BaseServiceImpl").formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").enableFileOverride()
.serviceTemplate("/templates/api/service.java")
.serviceImplTemplate("/templates/api/serviceImpl.java")
.mapperBuilder().mapperAnnotation(Mapper.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableFileOverride()
.mapperTemplate("/templates/api/mapper.java")
.mapperXmlTemplate("/templates/api/mapper.xml")
.controllerBuilder().superClass("org.springblade.core.boot.ctrl.BladeController").formatFileName("%sController").enableRestStyle().enableHyphenStyle().enableFileOverride()
.template("/templates/api/controller.java")
)
.injectionConfig(builder -> builder.beforeOutputFile(
(tableInfo, objectMap) -> System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size())
).customMap(customMap).customFile(customFile)
);
}
/**
* 获取jdbcUrl
*
* @param url jdbcUrl
* @return jdbcUrl
*/
private String getJdbcUrl(String url) {
DbType dbType = JdbcUtils.getDbType(url);
// 针对mysql做安全处理
if (dbType == DbType.MYSQL) {
url += "&allowLoadLocalInfile=false&allowUrlInLocalInfile=false&allowLoadLocalInfileInPath=false";
}
return url;
}
/**
* 获取配置文件
*
* @return 配置Props
*/
private Properties getProperties() {
// 读取配置文件
Resource resource = new ClassPathResource("/templates/code.properties");
Properties props = new Properties();
try {
props = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
/**
* 生成到项目中
*
* @return outputDir
*/
public String getOutputDir() {
return (Func.isBlank(packageDir) ? System.getProperty("user.dir") + "/blade-ops/blade-develop" : packageDir) + "/src/main/java";
}
/**
* 生成到Web项目中
*
* @return outputDir
*/
public String getOutputWebDir() {
return (Func.isBlank(packageWebDir) ? System.getProperty("user.dir") : packageWebDir) + "/src";
}
}
@@ -0,0 +1,244 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.develop.support;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Mapper;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import org.springblade.develop.constant.DevelopConstant;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
/**
* 代码生成器快速配置类
*
* @author Chill
*/
@Data
@Slf4j
public class BladeFastCodeGenerator {
/**
* 代码所在系统
*/
private String systemName = DevelopConstant.BOOT_NAME;
/**
* 代码模块名称
*/
private String codeName;
/**
* 代码所在服务名
*/
private String serviceName = "blade-service";
/**
* 代码生成的包名
*/
private String packageName = "org.springblade.test";
/**
* 代码后端生成的地址
*/
private String packageDir;
/**
* 需要去掉的表前缀
*/
private String[] tablePrefix = {"blade_"};
/**
* 需要生成的表名(两者只能取其一)
*/
private String[] includeTables = {"blade_test"};
/**
* 需要排除的表名(两者只能取其一)
*/
private String[] excludeTables = {};
/**
* 是否包含基础业务字段
*/
private Boolean hasSuperEntity = Boolean.TRUE;
/**
* 是否包含包装器
*/
private Boolean hasWrapper = Boolean.TRUE;
/**
* 是否包含服务名
*/
private Boolean hasServiceName = Boolean.FALSE;
/**
* 基础业务字段
*/
private String[] superEntityColumns = {"create_time", "create_user", "create_dept", "update_time", "update_user", "status", "is_deleted"};
/**
* 租户字段
*/
private String tenantColumn = "tenant_id";
/**
* 数据库驱动名
*/
private String driverName;
/**
* 数据库链接地址
*/
private String url;
/**
* 数据库用户名
*/
private String username;
/**
* 数据库密码
*/
private String password;
/**
* 代码生成执行
*/
public void run() {
Properties props = getProperties();
String url = Func.toStr(this.url, props.getProperty("spring.datasource.url"));
String username = Func.toStr(this.username, props.getProperty("spring.datasource.username"));
String password = Func.toStr(this.password, props.getProperty("spring.datasource.password"));
Map<String, Object> customMap = new HashMap<>(11);
customMap.put("codeName", codeName);
customMap.put("serviceName", serviceName);
customMap.put("packageName", packageName);
customMap.put("tenantColumn", tenantColumn);
customMap.put("hasSuperEntity", hasSuperEntity);
customMap.put("hasWrapper", hasWrapper);
customMap.put("hasServiceName", hasServiceName);
Map<String, String> customFile = new HashMap<>(15);
customFile.put("entityVO.java", "/templates/api-fast/entityVO.java.btl");
customFile.put("entityDTO.java", "/templates/api-fast/entityDTO.java.btl");
customFile.put("entityExcel.java", "/templates/api-fast/entityExcel.java.btl");
if (hasWrapper) {
customFile.put("wrapper.java", "/templates/api-fast/wrapper.java.btl");
}
FastAutoGenerator.create(url, username, password)
.globalConfig(builder -> builder.author(props.getProperty("author")).dateType(DateType.TIME_PACK).enableSwagger().outputDir(getOutputDir()).disableOpenDir())
.packageConfig(builder -> builder.parent(packageName).controller("controller").entity("pojo.entity").service("service").serviceImpl("service.impl").mapper("mapper").xml("mapper"))
.strategyConfig(builder -> builder.addTablePrefix(tablePrefix).addInclude(includeTables).addExclude(excludeTables)
.entityBuilder().naming(NamingStrategy.underline_to_camel).columnNaming(NamingStrategy.underline_to_camel).enableLombok().superClass("org.springblade.core.tenant.mp.TenantEntity").formatFileName("%sEntity").addSuperEntityColumns(superEntityColumns).enableFileOverride()
.javaTemplate("/templates/api-fast/entity.java")
.serviceBuilder().superServiceClass("org.springblade.core.mp.base.BaseService").superServiceImplClass("org.springblade.core.mp.base.BaseServiceImpl").formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").enableFileOverride()
.serviceTemplate("/templates/api-fast/service.java")
.serviceImplTemplate("/templates/api-fast/serviceImpl.java")
.mapperBuilder().mapperAnnotation(Mapper.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableFileOverride()
.mapperTemplate("/templates/api-fast/mapper.java")
.mapperXmlTemplate("/templates/api-fast/mapper.xml")
.controllerBuilder().superClass("org.springblade.core.boot.ctrl.BladeController").formatFileName("%sController").enableRestStyle().enableHyphenStyle().enableFileOverride()
.template("/templates/api-fast/controller.java")
)
.injectionConfig(builder -> builder.beforeOutputFile(
(tableInfo, objectMap) -> {
System.out.println("---------------------------------------------");
System.out.println("tableName: " + tableInfo.getName());
System.out.println("tableComment: " + tableInfo.getComment());
System.out.println("tableInfo: " + tableInfo.getEntityName());
System.out.println("result: success");
System.out.println("---------------------------------------------");
}
).customMap(customMap).customFile(customFile)
)
.templateEngine(new BeetlTemplateEngine() {
@Override
protected void outputCustomFile(List<CustomFile> customFiles, TableInfo tableInfo, Map<String, Object> objectMap) {
String entityName = tableInfo.getEntityName();
String entitySimpleName = StringUtil.removeSuffix(entityName, "Entity");
customFiles.forEach(customFile -> {
String key = customFile.getFileName();
String value = customFile.getTemplatePath();
String outputPath = getPathInfo(OutputFile.parent);
objectMap.put("entityKey", entitySimpleName);
objectMap.put("entityKeyPath", StringUtil.firstCharToLower(entitySimpleName));
if (StringUtil.equals(key, "entityVO.java")) {
outputPath = getOutputDir() + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "/pojo/vo" + StringPool.SLASH + entitySimpleName + "VO" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "entityDTO.java")) {
outputPath = getOutputDir() + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "/pojo/dto" + StringPool.SLASH + entitySimpleName + "DTO" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "entityExcel.java")) {
outputPath = getOutputDir() + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "/excel" + StringPool.SLASH + entitySimpleName + "Excel" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "wrapper.java")) {
outputPath = getOutputDir() + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "wrapper" + StringPool.SLASH + entitySimpleName + "Wrapper" + StringPool.DOT_JAVA;
}
outputFile(new File(String.valueOf(outputPath)), objectMap, value, Boolean.TRUE);
});
}
})
.execute();
}
/**
* 获取配置文件
*
* @return 配置Props
*/
private Properties getProperties() {
// 读取配置文件
Resource resource = new ClassPathResource("/templates/code.properties");
Properties props = new Properties();
try {
props = PropertiesLoaderUtils.loadProperties(resource);
} catch (IOException e) {
e.printStackTrace();
}
return props;
}
/**
* 生成到项目中
*
* @return outputDir
*/
public String getOutputDir() {
String projectPath = StringUtil.equals(systemName, DevelopConstant.CLOUD_NAME) ? "/blade-ops/blade-develop" : "";
return (Func.isBlank(packageDir) ? System.getProperty("user.dir") + projectPath : packageDir) + "/src/main/java";
}
}
@@ -0,0 +1,174 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package org.springblade.develop.support;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.generator.config.OutputFile;
import com.baomidou.mybatisplus.generator.config.builder.CustomFile;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.engine.BeetlTemplateEngine;
import lombok.AllArgsConstructor;
import org.springblade.core.tool.utils.Func;
import org.springblade.core.tool.utils.StringUtil;
import java.io.File;
import java.util.List;
import java.util.Map;
/**
* 代码模版生成实现类
*
* @author Chill
*/
@AllArgsConstructor
public class BladeTemplateEngine extends BeetlTemplateEngine {
private String outputDir;
private String outputWebDir;
/**
* 默认父级菜单ID(工作台菜单)
*/
private static final String PARENT_MENU_ID = "1123598815738675201";
@Override
protected void outputCustomFile(List<CustomFile> customFiles, TableInfo tableInfo, Map<String, Object> objectMap) {
String packageName = String.valueOf(objectMap.get("packageName"));
String serviceCode = String.valueOf(objectMap.get("serviceCode"));
String modelCode = String.valueOf(objectMap.get("modelCode"));
String entityName = String.valueOf(objectMap.get("modelClass"));
String menuId = String.valueOf(objectMap.get("menuId"));
Boolean hasMenuSql = Func.toBoolean(objectMap.get("hasMenuSql"));
String entityNameLower = entityName.toLowerCase();
customFiles.forEach(customFile -> {
String key = customFile.getFileName();
String value = customFile.getTemplatePath();
String outputPath = getPathInfo(OutputFile.parent);
objectMap.put("entityKey", entityNameLower);
if (StringUtil.equals(key, "menu.sql") && hasMenuSql) {
objectMap.put("parentMenuId", StringUtil.isBlank(menuId) ? PARENT_MENU_ID : menuId);
objectMap.put("menuId", IdWorker.getId());
objectMap.put("addMenuId", IdWorker.getId());
objectMap.put("editMenuId", IdWorker.getId());
objectMap.put("removeMenuId", IdWorker.getId());
objectMap.put("viewMenuId", IdWorker.getId());
outputPath = outputDir + StringPool.SLASH + "sql" + StringPool.SLASH + entityNameLower + ".menu.sql";
}
if (StringUtil.equals(key, "entityVO.java")) {
outputPath = outputDir + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "/pojo/vo" + StringPool.SLASH + entityName + "VO" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "entityDTO.java")) {
outputPath = outputDir + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "/pojo/dto" + StringPool.SLASH + entityName + "DTO" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "entityExcel.java")) {
outputPath = outputDir + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "/excel" + StringPool.SLASH + entityName + "Excel" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "wrapper.java")) {
outputPath = outputDir + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "wrapper" + StringPool.SLASH + entityName + "Wrapper" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "feign.java")) {
outputPath = outputDir + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "feign" + StringPool.SLASH + "I" + entityName + "Client" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "feignclient.java")) {
outputPath = outputDir + StringPool.SLASH + packageName.replace(StringPool.DOT, StringPool.SLASH) + StringPool.SLASH + "feign" + StringPool.SLASH + entityName + "Client" + StringPool.DOT_JAVA;
}
if (StringUtil.equals(key, "action.js")) {
outputPath = outputWebDir + StringPool.SLASH + "actions" + StringPool.SLASH + entityNameLower + ".js";
}
if (StringUtil.equals(key, "model.js")) {
outputPath = outputWebDir + StringPool.SLASH + "models" + StringPool.SLASH + entityNameLower + ".js";
}
if (StringUtil.equals(key, "service.js")) {
outputPath = outputWebDir + StringPool.SLASH + "services" + StringPool.SLASH + entityNameLower + ".js";
}
if (StringUtil.equals(key, "list.js")) {
outputPath = outputWebDir + StringPool.SLASH + "pages" + StringPool.SLASH + StringUtil.firstCharToUpper(modelCode) + StringPool.SLASH + entityName + StringPool.SLASH + entityName + ".js";
}
if (StringUtil.equals(key, "add.js")) {
outputPath = outputWebDir + StringPool.SLASH + "pages" + StringPool.SLASH + StringUtil.firstCharToUpper(modelCode) + StringPool.SLASH + entityName + StringPool.SLASH + entityName + "Add.js";
}
if (StringUtil.equals(key, "edit.js")) {
outputPath = outputWebDir + StringPool.SLASH + "pages" + StringPool.SLASH + StringUtil.firstCharToUpper(modelCode) + StringPool.SLASH + entityName + StringPool.SLASH + entityName + "Edit.js";
}
if (StringUtil.equals(key, "view.js")) {
outputPath = outputWebDir + StringPool.SLASH + "pages" + StringPool.SLASH + StringUtil.firstCharToUpper(modelCode) + StringPool.SLASH + entityName + StringPool.SLASH + entityName + "View.js";
}
if (StringUtil.equals(key, "api.js")) {
outputPath = outputWebDir + StringPool.SLASH + "api" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + ".js";
}
if (StringUtil.equals(key, "option.js")) {
outputPath = outputWebDir + StringPool.SLASH + "option" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + ".js";
}
if (StringUtil.equals(key, "crud.vue")) {
outputPath = outputWebDir + StringPool.SLASH + "views" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + ".vue";
}
if (StringUtil.equals(key, "sub.vue")) {
outputPath = outputWebDir + StringPool.SLASH + "views" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + "Sub.vue";
}
if (StringUtil.equals(key, "data.ts")) {
outputPath = outputWebDir + StringPool.SLASH + "api" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + ".ts";
}
if (StringUtil.equals(key, "data.data.ts")) {
outputPath = outputWebDir + StringPool.SLASH + "views" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + StringPool.SLASH + modelCode + ".data.ts";
}
if (StringUtil.equals(key, "index.vue")) {
outputPath = outputWebDir + StringPool.SLASH + "views" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + StringPool.SLASH + "index.vue";
}
if (StringUtil.equals(key, "Modal.vue")) {
outputPath = outputWebDir + StringPool.SLASH + "views" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + StringPool.SLASH + entityName + "Modal.vue";
}
if (StringUtil.equals(key, "lemonSub.vue")) {
outputPath = outputWebDir + StringPool.SLASH + "views" + StringPool.SLASH + serviceCode + StringPool.SLASH + modelCode + StringPool.SLASH + entityName + "Sub.vue";
}
outputFile(new File(String.valueOf(outputPath)), objectMap, value, Boolean.TRUE);
});
}
}
@@ -0,0 +1,10 @@
#默认配置
ENGINE = org.beetl.core.engine.FastRuntimeEngine
#开始结束占位符
DELIMITER_PLACEHOLDER_START = ${
DELIMITER_PLACEHOLDER_END = }
#开始结束标签
DELIMITER_STATEMENT_START = #
DELIMITER_STATEMENT_END = null
@@ -0,0 +1,212 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Controller};
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import jakarta.validation.Valid;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.annotation.IsAdmin;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import ${packageName!}.pojo.vo.${entityKey!}VO;
import ${packageName!}.excel.${entityKey!}Excel;
#if(hasWrapper) {
import ${packageName!}.wrapper.${entityKey!}Wrapper;
#}
import ${packageName!}.service.${table.serviceName!};
#if(isNotEmpty(superControllerClassPackage)){
import ${superControllerClassPackage!};
#}
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.tool.constant.BladeConstant;
import java.util.Map;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
/**
* ${table.comment!} 控制器
*
* @author ${author!}
* @since ${date!}
*/
@RestController
@AllArgsConstructor
#if(hasServiceName) {
@RequestMapping("${serviceName!}/${entityKeyPath!}")
#}else{
@RequestMapping("/${entityKeyPath!}")
#}
@Tag(name = "${table.comment!}", description = "${table.comment!}接口")
#if(isNotEmpty(superControllerClass)){
public class ${table.controllerName!} extends ${superControllerClass!} {
#}
#else{
public class ${table.controllerName!} {
#}
private final ${table.serviceName!} ${entityKeyPath!}Service;
#if(hasWrapper){
/**
* ${table.comment!} 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 1)
@Operation(summary = "详情", description = "传入${entityKeyPath!}")
public R<${entityKey!}VO> detail(${entityKey!}Entity ${entityKeyPath!}) {
${entityKey!}Entity detail = ${entityKeyPath!}Service.getOne(Condition.getQueryWrapper(${entityKeyPath!}));
return R.data(${entityKey!}Wrapper.build().entityVO(detail));
}
/**
* ${table.comment!} 分页
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入${entityKeyPath!}")
public R<IPage<${entityKey!}VO>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> ${entityKeyPath!}, Query query) {
IPage<${entityKey!}Entity> pages = ${entityKeyPath!}Service.page(Condition.getPage(query), Condition.getQueryWrapper(${entityKeyPath!}, ${entityKey!}Entity.class));
return R.data(${entityKey!}Wrapper.build().pageVO(pages));
}
#}else{
/**
* ${table.comment!} 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 1)
@Operation(summary = "详情", description = "传入${entityKeyPath!}")
public R<${entityKey!}Entity> detail(${entityKey!}Entity ${entityKeyPath!}) {
${entityKey!}Entity detail = ${entityKeyPath!}Service.getOne(Condition.getQueryWrapper(${entityKeyPath!}));
return R.data(detail);
}
/**
* ${table.comment!} 分页
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入${entityKeyPath!}")
public R<IPage<${entityKey!}Entity>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> ${entityKeyPath!}, Query query) {
IPage<${entityKey!}Entity> pages = ${entityKeyPath!}Service.page(Condition.getPage(query), Condition.getQueryWrapper(${entityKeyPath!}, ${entityKey!}Entity.class));
return R.data(pages);
}
#}
/**
* ${table.comment!} 自定义分页
*/
@GetMapping("/page")
@ApiOperationSupport(order = 3)
@Operation(summary = "分页", description = "传入${entityKeyPath!}")
public R<IPage<${entityKey!}VO>> page(${entityKey!}VO ${entityKeyPath!}, Query query) {
IPage<${entityKey!}VO> pages = ${entityKeyPath!}Service.select${entityKey!}Page(Condition.getPage(query), ${entityKeyPath!});
return R.data(pages);
}
/**
* ${table.comment!} 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 4)
@Operation(summary = "新增", description = "传入${entityKeyPath!}")
public R save(@Valid @RequestBody ${entityKey!}Entity ${entityKeyPath!}) {
return R.status(${entityKeyPath!}Service.save(${entityKeyPath!}));
}
/**
* ${table.comment!} 修改
*/
@PostMapping("/update")
@ApiOperationSupport(order = 5)
@Operation(summary = "修改", description = "传入${entityKeyPath!}")
public R update(@Valid @RequestBody ${entityKey!}Entity ${entityKeyPath!}) {
return R.status(${entityKeyPath!}Service.updateById(${entityKeyPath!}));
}
/**
* ${table.comment!} 新增或修改
*/
@PostMapping("/submit")
@ApiOperationSupport(order = 6)
@Operation(summary = "新增或修改", description = "传入${entityKeyPath!}")
public R submit(@Valid @RequestBody ${entityKey!}Entity ${entityKeyPath!}) {
return R.status(${entityKeyPath!}Service.saveOrUpdate(${entityKeyPath!}));
}
#if(hasSuperEntity){
/**
* ${table.comment!} 删除
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 7)
@Operation(summary = "逻辑删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(${entityKeyPath!}Service.deleteLogic(Func.toLongList(ids)));
}
#}else{
/**
* ${table.comment!} 删除
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 7)
@Operation(summary = "删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(${entityKeyPath!}Service.removeByIds(Func.toLongList(ids)));
}
#}
/**
* 导出数据
*/
@IsAdmin
@GetMapping("/export-${entityKeyPath!}")
@ApiOperationSupport(order = 8)
@Operation(summary = "导出数据", description = "传入${entityKeyPath!}")
public void export${entityKey!}(@Parameter(hidden = true) @RequestParam Map<String, Object> ${entityKeyPath!}, BladeUser bladeUser, HttpServletResponse response) {
QueryWrapper<${entityKey!}Entity> queryWrapper = Condition.getQueryWrapper(${entityKeyPath!}, ${entityKey!}Entity.class);
//if (!AuthUtil.isAdministrator()) {
// queryWrapper.lambda().eq(${entity!}::getTenantId, bladeUser.getTenantId());
//}
//queryWrapper.lambda().eq(${entityKey!}Entity::getIsDeleted, BladeConstant.DB_NOT_DELETED);
List<${entityKey!}Excel> list = ${entityKeyPath!}Service.export${entityKey!}(queryWrapper);
ExcelUtil.export(response, "${table.comment!}数据" + DateUtil.time(), "${table.comment!}数据表", list, ${entityKey!}Excel.class);
}
}
@@ -0,0 +1,100 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Entity!};
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
#for(x in table.importPackages){
#if(isNotEmpty(x)){
#if(hasSuperEntity&&!strutil.contain(x,"Serializable")){
import ${x!};
#}
#if(!hasSuperEntity&&!strutil.contain(x,"TenantEntity")){
import ${x!};
#}
#}
#}
#if(hasSuperEntity){
import lombok.EqualsAndHashCode;
#}else{
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
#}
import java.io.Serial;
/**
* ${table.comment!} 实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@TableName("${table.name!}")
@Schema(description = "${entity!}对象")
#if(hasSuperEntity){
@EqualsAndHashCode(callSuper = true)
public class ${entityKey!}Entity extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
#}else{
public class ${entityKey!}Entity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@JsonSerialize(using = ToStringSerializer.class)
@Schema(description = "主键")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
#}
#for(x in table.fields) {
#if(hasSuperEntity){
#if(x.propertyName!="id"&&x.propertyName!="createUser"&&x.propertyName!="createDept"&&x.propertyName!="createTime"&&x.propertyName!="updateUser"&&x.propertyName!="updateTime"&&x.propertyName!="status"&&x.propertyName!="isDeleted"&&x.propertyName!="tenantId"){
/**
* ${x.comment!}
*/
@Schema(description = "${x.comment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}else{
#if(x.propertyName!="id"){
/**
* ${x.comment!}
*/
@Schema(description = "${x.comment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}
#}
}
@@ -0,0 +1,45 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"entity","dto")};
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* ${table.comment!} 数据传输对象实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ${entityKey!}DTO extends ${entityKey!}Entity {
@Serial
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,69 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"pojo.entity","excel")};
import lombok.Data;
#for(x in table.importPackages){
#if(isNotEmpty(x)&&!strutil.contain(x,"TableName")&&!strutil.contain(x,"TenantEntity")){
import ${x!};
#}
#}
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentRowHeight;
import cn.idev.excel.annotation.write.style.HeadRowHeight;
import java.io.Serial;
/**
* ${table.comment!} Excel实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@ColumnWidth(25)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class ${entityKey!}Excel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
#for(x in table.fields) {
#if(x.propertyName!="createUser"&&x.propertyName!="createDept"&&x.propertyName!="createTime"&&x.propertyName!="updateUser"&&x.propertyName!="updateTime"){
/**
* ${x.comment!}
*/
@ColumnWidth(20)
@ExcelProperty("${x.comment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}
}
@@ -0,0 +1,45 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"entity","vo")};
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* ${table.comment!} 视图实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ${entityKey!}VO extends ${entityKey!}Entity {
@Serial
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,62 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Mapper!};
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import ${packageName!}.pojo.vo.${entityKey!}VO;
import ${packageName!}.excel.${entityKey!}Excel;
import ${superMapperClassPackage!};
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* ${table.comment!} Mapper 接口
*
* @author ${author!}
* @since ${date!}
*/
public interface ${table.mapperName!} extends ${superMapperClass!}<${entityKey!}Entity> {
/**
* 自定义分页
*
* @param page 分页参数
* @param ${entityKeyPath!} 查询参数
* @return List<${entityKey!}VO>
*/
List<${entityKey!}VO> select${entityKey!}Page(IPage page, ${entityKey!}VO ${entityKeyPath!});
/**
* 获取导出数据
*
* @param queryWrapper 查询条件
* @return List<${entityKey!}Excel>
*/
List<${entityKey!}Excel> export${entityKey!}(@Param("ew") Wrapper<${entityKey!}Entity> queryWrapper);
}
@@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper!}.${table.mapperName!}">
#if(enableCache){
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#}
<!-- 通用查询映射结果 -->
<resultMap id="${entityKeyPath!}ResultMap" type="${package.Entity!}.${entityKey!}Entity">
#for(x in table.fields) {
<result column="${x.name!}" property="${x.propertyName!}"/>
#}
</resultMap>
<select id="select${entityKey!}Page" resultMap="${entityKeyPath!}ResultMap">
select * from ${table.name} where is_deleted = 0
</select>
<select id="export${entityKey!}" resultType="${packageName!}.excel.${entityKey!}Excel">
SELECT * FROM ${table.name!} \${ew.customSqlSegment}
</select>
</mapper>
@@ -0,0 +1,68 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Service!};
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import ${packageName!}.pojo.vo.${entityKey!}VO;
import ${packageName!}.excel.${entityKey!}Excel;
import com.baomidou.mybatisplus.core.metadata.IPage;
#if(hasSuperEntity){
import ${superServiceClassPackage!};
#}else{
import com.baomidou.mybatisplus.extension.service.IService;
#}
import java.util.List;
/**
* ${table.comment!} 服务类
*
* @author ${author!}
* @since ${date!}
*/
#if(hasSuperEntity){
public interface ${table.serviceName!} extends ${superServiceClass!}<${entity!}> {
#}else{
public interface ${table.serviceName!} extends IService<${entity!}> {
#}
/**
* 自定义分页
*
* @param page 分页参数
* @param ${entityKeyPath!} 查询参数
* @return IPage<${entityKey!}VO>
*/
IPage<${entityKey!}VO> select${entityKey!}Page(IPage<${entityKey!}VO> page, ${entityKey!}VO ${entityKeyPath!});
/**
* 导出数据
*
* @param queryWrapper 查询条件
* @return List<${entityKey!}Excel>
*/
List<${entityKey!}Excel> export${entityKey!}(Wrapper<${entityKey!}Entity> queryWrapper);
}
@@ -0,0 +1,70 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.ServiceImpl!};
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import ${packageName!}.pojo.vo.${entityKey!}VO;
import ${packageName!}.excel.${entityKey!}Excel;
import ${packageName!}.mapper.${table.mapperName!};
import ${packageName!}.service.${table.serviceName!};
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
#if(hasSuperEntity){
import ${superServiceImplClassPackage!};
#}else{
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
#}
import java.util.List;
/**
* ${table.comment!} 服务实现类
*
* @author ${author!}
* @since ${date!}
*/
@Service
#if(hasSuperEntity){
public class ${table.serviceImplName!} extends ${superServiceImplClass!}<${table.mapperName!}, ${entity!}> implements ${table.serviceName!} {
#}else{
public class ${table.serviceImplName!} extends ServiceImpl<${table.mapperName!}, ${entity!}> implements ${table.serviceName!} {
#}
@Override
public IPage<${entityKey!}VO> select${entityKey!}Page(IPage<${entityKey!}VO> page, ${entityKey!}VO ${entityKeyPath!}) {
return page.setRecords(baseMapper.select${entityKey!}Page(page, ${entityKeyPath!}));
}
@Override
public List<${entityKey!}Excel> export${entityKey!}(Wrapper<${entityKey!}Entity> queryWrapper) {
List<${entityKey!}Excel> ${entityKeyPath!}List = baseMapper.export${entityKey!}(queryWrapper);
//${entityKeyPath!}List.forEach(${entityKeyPath!} -> {
// ${entityKeyPath!}.setTypeName(DictCache.getValue(DictEnum.YES_NO, ${entity!}.getType()));
//});
return ${entityKeyPath!}List;
}
}
@@ -0,0 +1,58 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"pojo.entity","wrapper")};
import org.springblade.core.mp.support.BaseEntityWrapper;
import org.springblade.core.tool.utils.BeanUtil;
import ${packageName!}.pojo.entity.${entityKey!}Entity;
import ${packageName!}.pojo.vo.${entityKey!}VO;
import java.util.Objects;
/**
* ${table.comment!} 包装类,返回视图层所需的字段
*
* @author ${author!}
* @since ${date!}
*/
public class ${entityKey!}Wrapper extends BaseEntityWrapper<${entityKey!}Entity, ${entityKey!}VO> {
public static ${entityKey!}Wrapper build() {
return new ${entityKey!}Wrapper();
}
@Override
public ${entityKey!}VO entityVO(${entityKey!}Entity ${entityKeyPath!}) {
${entityKey!}VO ${entityKeyPath!}VO = Objects.requireNonNull(BeanUtil.copyProperties(${entityKeyPath!}, ${entityKey!}VO.class));
//User createUser = UserCache.getUser(${entityKeyPath!}.getCreateUser());
//User updateUser = UserCache.getUser(${entityKeyPath!}.getUpdateUser());
//${entityKeyPath!}VO.setCreateUserName(createUser.getName());
//${entityKeyPath!}VO.setUpdateUserName(updateUser.getName());
return ${entityKeyPath!}VO;
}
}
@@ -0,0 +1,252 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Controller};
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;
import lombok.AllArgsConstructor;
import jakarta.validation.Valid;
import org.springblade.core.secure.BladeUser;
import org.springblade.core.secure.annotation.IsAdmin;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import org.springblade.core.tool.api.R;
import org.springblade.core.tool.utils.Func;
import org.springframework.web.bind.annotation.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import ${packageName!}.pojo.vo.${modelClass!}VO;
import ${packageName!}.excel.${modelClass!}Excel;
#if(hasWrapper) {
import ${packageName!}.wrapper.${modelClass!}Wrapper;
#}
import ${packageName!}.service.I${modelClass!}Service;
#if(isNotEmpty(superControllerClassPackage)){
import ${superControllerClassPackage!};
#}
#if(templateType=="tree"&&!hasWrapper){
import ${packageName!}.wrapper.${modelClass!}Wrapper;
#}
import org.springblade.core.tool.utils.DateUtil;
import org.springblade.core.excel.util.ExcelUtil;
import org.springblade.core.tool.constant.BladeConstant;
import java.util.Map;
import java.util.List;
import jakarta.servlet.http.HttpServletResponse;
/**
* ${codeName!} 控制器
*
* @author ${author!}
* @since ${date!}
*/
@RestController
@AllArgsConstructor
#if(hasServiceName) {
@RequestMapping("${serviceName!}/${modelCode!}")
#}else{
@RequestMapping("/${modelCode!}")
#}
@Tag(name = "${codeName!}", description = "${codeName!}接口")
#if(isNotEmpty(superControllerClass)){
public class ${modelClass!}Controller extends ${superControllerClass!} {
#}
#else{
public class ${modelClass!}Controller {
#}
private final I${modelClass!}Service ${modelCode!}Service;
#if(hasWrapper){
/**
* ${codeName!} 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 1)
@Operation(summary = "详情", description = "传入${modelCode!}")
public R<${modelClass!}VO> detail(${modelClass!}Entity ${modelCode!}) {
${modelClass!}Entity detail = ${modelCode!}Service.getOne(Condition.getQueryWrapper(${modelCode!}));
return R.data(${modelClass!}Wrapper.build().entityVO(detail));
}
#if(templateType=="tree"){
/**
* ${codeName!} 树列表
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入${modelCode!}")
public R<List<${modelClass!}VO>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> ${modelCode!}, BladeUser bladeUser) {
QueryWrapper<${modelClass!}Entity> queryWrapper = Condition.getQueryWrapper(${modelCode!}, ${modelClass!}Entity.class);
List<${modelClass!}Entity> list = ${modelCode!}Service.list((!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)) ? queryWrapper.lambda().eq(${modelClass!}Entity::getTenantId, bladeUser.getTenantId()) : queryWrapper);
return R.data(${modelClass!}Wrapper.build().treeNodeVO(list));
}
#}else{
/**
* ${codeName!} 分页
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入${modelCode!}")
public R<IPage<${modelClass!}VO>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> ${modelCode!}, Query query) {
IPage<${modelClass!}Entity> pages = ${modelCode!}Service.page(Condition.getPage(query), Condition.getQueryWrapper(${modelCode!}, ${modelClass!}Entity.class));
return R.data(${modelClass!}Wrapper.build().pageVO(pages));
}
#}
#}else{
/**
* ${codeName!} 详情
*/
@GetMapping("/detail")
@ApiOperationSupport(order = 1)
@Operation(summary = "详情", description = "传入${modelCode!}")
public R<${modelClass!}Entity> detail(${modelClass!}Entity ${modelCode!}) {
${modelClass!}Entity detail = ${modelCode!}Service.getOne(Condition.getQueryWrapper(${modelCode!}));
return R.data(detail);
}
#if(templateType=="tree"){
/**
* ${codeName!} 树列表
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入notice")
public R<List<${modelClass!}VO>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> ${modelCode!}, BladeUser bladeUser) {
QueryWrapper<${modelClass!}Entity> queryWrapper = Condition.getQueryWrapper(${modelCode!}, ${modelClass!}Entity.class);
List<${modelClass!}Entity> list = ${modelCode!}Service.list((!bladeUser.getTenantId().equals(BladeConstant.ADMIN_TENANT_ID)) ? queryWrapper.lambda().eq(${modelClass!}Entity::getTenantId, bladeUser.getTenantId()) : queryWrapper);
return R.data(${modelClass!}Wrapper.build().treeNodeVO(list));
}
#}else{
/**
* ${codeName!} 分页
*/
@GetMapping("/list")
@ApiOperationSupport(order = 2)
@Operation(summary = "分页", description = "传入${modelCode!}")
public R<IPage<${modelClass!}Entity>> list(@Parameter(hidden = true) @RequestParam Map<String, Object> ${modelCode!}, Query query) {
IPage<${modelClass!}Entity> pages = ${modelCode!}Service.page(Condition.getPage(query), Condition.getQueryWrapper(${modelCode!}, ${modelClass!}Entity.class));
return R.data(pages);
}
#}
#}
/**
* ${codeName!} 自定义分页
*/
@GetMapping("/page")
@ApiOperationSupport(order = 3)
@Operation(summary = "分页", description = "传入${modelCode!}")
public R<IPage<${modelClass!}VO>> page(${modelClass!}VO ${modelCode!}, Query query) {
IPage<${modelClass!}VO> pages = ${modelCode!}Service.select${modelClass!}Page(Condition.getPage(query), ${modelCode!});
return R.data(pages);
}
/**
* ${codeName!} 新增
*/
@PostMapping("/save")
@ApiOperationSupport(order = 4)
@Operation(summary = "新增", description = "传入${modelCode!}")
public R save(@Valid @RequestBody ${modelClass!}Entity ${modelCode!}) {
return R.status(${modelCode!}Service.save(${modelCode!}));
}
/**
* ${codeName!} 修改
*/
@PostMapping("/update")
@ApiOperationSupport(order = 5)
@Operation(summary = "修改", description = "传入${modelCode!}")
public R update(@Valid @RequestBody ${modelClass!}Entity ${modelCode!}) {
return R.status(${modelCode!}Service.updateById(${modelCode!}));
}
/**
* ${codeName!} 新增或修改
*/
@PostMapping("/submit")
@ApiOperationSupport(order = 6)
@Operation(summary = "新增或修改", description = "传入${modelCode!}")
public R submit(@Valid @RequestBody ${modelClass!}Entity ${modelCode!}) {
return R.status(${modelCode!}Service.saveOrUpdate(${modelCode!}));
}
#if(hasSuperEntity){
/**
* ${codeName!} 删除
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 7)
@Operation(summary = "逻辑删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(${modelCode!}Service.deleteLogic(Func.toLongList(ids)));
}
#}else{
/**
* ${codeName!} 删除
*/
@PostMapping("/remove")
@ApiOperationSupport(order = 7)
@Operation(summary = "删除", description = "传入ids")
public R remove(@Parameter(description = "主键集合", required = true) @RequestParam String ids) {
return R.status(${modelCode!}Service.removeByIds(Func.toLongList(ids)));
}
#}
#if(templateType=="tree"){
/**
* ${codeName!} 树形结构
*/
@GetMapping("/tree")
@ApiOperationSupport(order = 8)
@Operation(summary = "树形结构", description = "树形结构")
public R<List<${modelClass!}VO>> tree(String tenantId, BladeUser bladeUser) {
List<${modelClass!}VO> tree = ${modelCode!}Service.tree(Func.toStrWithEmpty(tenantId, bladeUser.getTenantId()));
return R.data(tree);
}
#}
/**
* 导出数据
*/
@IsAdmin
@GetMapping("/export-${modelCode!}")
@ApiOperationSupport(order = 9)
@Operation(summary = "导出数据", description = "传入${modelCode!}")
public void export${modelClass!}(@Parameter(hidden = true) @RequestParam Map<String, Object> ${modelCode!}, BladeUser bladeUser, HttpServletResponse response) {
QueryWrapper<${modelClass!}Entity> queryWrapper = Condition.getQueryWrapper(${modelCode!}, ${modelClass!}Entity.class);
//if (!AuthUtil.isAdministrator()) {
// queryWrapper.lambda().eq(${modelClass!}::getTenantId, bladeUser.getTenantId());
//}
//queryWrapper.lambda().eq(${modelClass!}Entity::getIsDeleted, BladeConstant.DB_NOT_DELETED);
List<${modelClass!}Excel> list = ${modelCode!}Service.export${modelClass!}(queryWrapper);
ExcelUtil.export(response, "${codeName!}数据" + DateUtil.time(), "${codeName!}数据表", list, ${modelClass!}Excel.class);
}
}
@@ -0,0 +1,98 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Entity!};
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import com.baomidou.mybatisplus.annotation.TableName;
#for(x in propertyImport){
#if(isNotEmpty(x)){
import ${x!};
#}
#}
#if(hasSuperEntity){
import lombok.EqualsAndHashCode;
import org.springblade.core.tenant.mp.TenantEntity;
#}else{
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import java.io.Serializable;
#}
import java.io.Serial;
/**
* ${codeName!} 实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@TableName("${model.modelTable!}")
@Schema(description = "${modelClass!}对象")
#if(hasSuperEntity){
@EqualsAndHashCode(callSuper = true)
public class ${modelClass!}Entity extends TenantEntity {
@Serial
private static final long serialVersionUID = 1L;
#}else{
public class ${modelClass!}Entity implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键
*/
@JsonSerialize(using = ToStringSerializer.class)
@Schema(description = "主键")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
#}
#for(x in prototypes) {
#if(hasSuperEntity){
#if(x.propertyName!="id"&&x.propertyName!="createUser"&&x.propertyName!="createDept"&&x.propertyName!="createTime"&&x.propertyName!="updateUser"&&x.propertyName!="updateTime"&&x.propertyName!="status"&&x.propertyName!="isDeleted"&&x.propertyName!="tenantId"){
/**
* ${x.jdbcComment!}
*/
@Schema(description = "${x.jdbcComment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}else{
#if(x.propertyName!="id"){
/**
* ${x.jdbcComment!}
*/
@Schema(description = "${x.jdbcComment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}
#}
}
@@ -0,0 +1,45 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"entity","dto")};
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.io.Serial;
/**
* ${codeName!} 数据传输对象实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@EqualsAndHashCode(callSuper = true)
public class ${modelClass!}DTO extends ${modelClass!}Entity {
@Serial
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,70 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"pojo.entity","excel")};
import lombok.Data;
#for(x in propertyImport){
#if(isNotEmpty(x)){
import ${x!};
#}
#}
import cn.idev.excel.annotation.ExcelProperty;
import cn.idev.excel.annotation.write.style.ColumnWidth;
import cn.idev.excel.annotation.write.style.ContentRowHeight;
import cn.idev.excel.annotation.write.style.HeadRowHeight;
import java.io.Serializable;
import java.io.Serial;
/**
* ${codeName!} Excel实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@ColumnWidth(25)
@HeadRowHeight(20)
@ContentRowHeight(18)
public class ${modelClass!}Excel implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
#for(x in prototypes) {
#if(x.propertyName!="createUser"&&x.propertyName!="createDept"&&x.propertyName!="createTime"&&x.propertyName!="updateUser"&&x.propertyName!="updateTime"&&x.propertyName!="status"){
/**
* ${x.jdbcComment!}
*/
@ColumnWidth(20)
@ExcelProperty("${x.jdbcComment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}
}
@@ -0,0 +1,101 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"entity","vo")};
import ${packageName!}.pojo.entity.${modelClass!}Entity;
#if(templateType=="tree"){
import org.springblade.core.tool.node.INode;
#}
import lombok.Data;
import lombok.EqualsAndHashCode;
#if(templateType=="tree"){
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
import java.util.ArrayList;
import java.util.List;
#}
import java.io.Serial;
/**
* ${codeName!} 视图实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@EqualsAndHashCode(callSuper = true)
#if(templateType=="tree"){
public class ${modelClass!}VO extends ${modelClass!}Entity implements INode<${modelClass!}VO> {
@Serial
private static final long serialVersionUID = 1L;
/**
* 主键ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long id;
/**
* 父节点ID
*/
@JsonSerialize(using = ToStringSerializer.class)
private Long parentId;
/**
* 父节点名称
*/
private String parentName;
/**
* 子孙节点
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private List<${modelClass!}VO> children;
/**
* 是否有子孙节点
*/
@JsonInclude(JsonInclude.Include.NON_EMPTY)
private Boolean hasChildren;
@Override
public List<${modelClass!}VO> getChildren() {
if (this.children == null) {
this.children = new ArrayList<>();
}
return this.children;
}
}
#}else{
public class ${modelClass!}VO extends ${modelClass!}Entity {
@Serial
private static final long serialVersionUID = 1L;
}
#}
@@ -0,0 +1,58 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"pojo.entity","feign")};
import org.springblade.core.mp.support.BladePage;
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* ${codeName!} Feign接口类
*
* @author ${author!}
* @since ${date!}
*/
@FeignClient(
value = "${serviceName!}"
)
public interface I${modelClass!}Client {
String API_PREFIX = "/feign/client/${modelCode!}";
String TOP = API_PREFIX + "/top";
/**
* 获取${codeName!}列表
*
* @param current 页号
* @param size 页数
* @return BladePage
*/
@GetMapping(TOP)
BladePage<${modelClass!}Entity> top(@RequestParam("current") Integer current, @RequestParam("size") Integer size);
}
@@ -0,0 +1,62 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"pojo.entity","feign")};
import com.baomidou.mybatisplus.core.metadata.IPage;
import lombok.AllArgsConstructor;
import org.springblade.core.mp.support.BladePage;
import org.springblade.core.mp.support.Condition;
import org.springblade.core.mp.support.Query;
import io.swagger.v3.oas.annotations.Hidden;
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import ${packageName!}.service.I${modelClass!}Service;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* ${codeName!} Feign实现类
*
* @author ${author!}
* @since ${date!}
*/
@Hidden
@RestController
@AllArgsConstructor
public class ${modelClass!}Client implements I${modelClass!}Client {
private final I${modelClass!}Service ${modelCode!}Service;
@Override
@GetMapping(TOP)
public BladePage<${modelClass!}Entity> top(Integer current, Integer size) {
Query query = new Query();
query.setCurrent(current);
query.setSize(size);
IPage<${modelClass!}Entity> page = ${modelCode!}Service.page(Condition.getPage(query));
return BladePage.of(page);
}
}
@@ -0,0 +1,72 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Mapper!};
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import ${packageName!}.pojo.vo.${modelClass!}VO;
import ${packageName!}.excel.${modelClass!}Excel;
import ${superMapperClassPackage!};
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* ${codeName!} Mapper 接口
*
* @author ${author!}
* @since ${date!}
*/
public interface ${modelClass!}Mapper extends ${superMapperClass!}<${modelClass!}Entity> {
/**
* 自定义分页
*
* @param page 分页参数
* @param ${modelCode!} 查询参数
* @return List<${modelClass!}VO>
*/
List<${modelClass!}VO> select${modelClass!}Page(IPage page, ${modelClass!}VO ${modelCode!});
#if(templateType=="tree"){
/**
* 获取树形节点
*
* @param tenantId 租户ID
* @return List<${modelClass!}VO>
*/
List<${modelClass!}VO> tree(String tenantId);
#}
/**
* 获取导出数据
*
* @param queryWrapper 查询条件
* @return List<${modelClass!}Excel>
*/
List<${modelClass!}Excel> export${modelClass!}(@Param("ew") Wrapper<${modelClass!}Entity> queryWrapper);
}
@@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${package.Mapper!}.${modelClass!}Mapper">
#if(enableCache){
<!-- 开启二级缓存 -->
<cache type="org.mybatis.caches.ehcache.LoggingEhcache"/>
#}
<!-- 通用查询映射结果 -->
<resultMap id="${modelCode!}ResultMap" type="${package.Entity!}.${modelClass!}Entity">
#for(x in prototypes) {
<result column="${x.jdbcName!}" property="${x.propertyName!}"/>
#}
</resultMap>
#if(templateType=="tree"){
<resultMap id="treeNodeResultMap" type="org.springblade.core.tool.node.TreeNode">
<id column="id" property="id"/>
<result column="parent_id" property="parentId"/>
<result column="title" property="title"/>
<result column="value" property="value"/>
<result column="key" property="key"/>
</resultMap>
#}
<select id="select${modelClass!}Page" resultMap="${modelCode!}ResultMap">
select * from ${model.modelTable} where is_deleted = 0
</select>
#if(templateType=="tree"){
<select id="tree" resultMap="treeNodeResultMap">
select ${treeId!} as id, ${treePid!} as parent_id, ${treeName!} as title, ${treeId!} as "value", ${treeId!} as "key" from ${model.modelTable!} where is_deleted = 0
<if test="_parameter!=null">
and tenant_id = \#{_parameter}
</if>
</select>
#}
<select id="export${modelClass!}" resultType="${packageName!}.excel.${modelClass!}Excel">
SELECT * FROM ${model.modelTable!} \${ew.customSqlSegment}
</select>
</mapper>
@@ -0,0 +1,78 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.Service!};
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import ${packageName!}.pojo.vo.${modelClass!}VO;
import ${packageName!}.excel.${modelClass!}Excel;
import com.baomidou.mybatisplus.core.metadata.IPage;
#if(hasSuperEntity){
import ${superServiceClassPackage!};
#}else{
import com.baomidou.mybatisplus.extension.service.IService;
#}
import java.util.List;
/**
* ${codeName!} 服务类
*
* @author ${author!}
* @since ${date!}
*/
#if(hasSuperEntity){
public interface I${modelClass!}Service extends ${superServiceClass!}<${modelClass!}Entity> {
#}else{
public interface I${modelClass!}Service extends IService<${modelClass!}Entity> {
#}
/**
* 自定义分页
*
* @param page 分页参数
* @param ${modelCode!} 查询参数
* @return IPage<${modelClass!}VO>
*/
IPage<${modelClass!}VO> select${modelClass!}Page(IPage<${modelClass!}VO> page, ${modelClass!}VO ${modelCode!});
#if(templateType=="tree"){
/**
* 树形结构
*
* @param tenantId 租户ID
* @return List<${modelClass!}VO>
*/
List<${modelClass!}VO> tree(String tenantId);
#}
/**
* 导出数据
*
* @param queryWrapper 查询条件
* @return List<${modelClass!}Excel>
*/
List<${modelClass!}Excel> export${modelClass!}(Wrapper<${modelClass!}Entity> queryWrapper);
}
@@ -0,0 +1,80 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${package.ServiceImpl!};
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import ${packageName!}.pojo.vo.${modelClass!}VO;
import ${packageName!}.excel.${modelClass!}Excel;
import ${packageName!}.mapper.${model.modelClass!}Mapper;
import ${packageName!}.service.I${model.modelClass!}Service;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
#if(templateType=="tree"){
import org.springblade.core.tool.node.ForestNodeMerger;
#}
#if(hasSuperEntity){
import ${superServiceImplClassPackage!};
#}else{
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
#}
import java.util.List;
/**
* ${codeName!} 服务实现类
*
* @author ${author!}
* @since ${date!}
*/
@Service
#if(hasSuperEntity){
public class ${modelClass!}ServiceImpl extends ${superServiceImplClass!}<${modelClass!}Mapper, ${modelClass!}Entity> implements I${model.modelClass!}Service {
#}else{
public class ${modelClass!}ServiceImpl extends ServiceImpl<${modelClass!}Mapper, ${modelClass!}Entity> implements I${model.modelClass!}Service {
#}
@Override
public IPage<${modelClass!}VO> select${modelClass!}Page(IPage<${modelClass!}VO> page, ${modelClass!}VO ${modelCode!}) {
return page.setRecords(baseMapper.select${modelClass!}Page(page, ${modelCode!}));
}
#if(templateType=="tree"){
@Override
public List<${modelClass!}VO> tree(String tenantId) {
return ForestNodeMerger.merge(baseMapper.tree(tenantId));
}
#}
@Override
public List<${modelClass!}Excel> export${modelClass!}(Wrapper<${modelClass!}Entity> queryWrapper) {
List<${modelClass!}Excel> ${modelCode!}List = baseMapper.export${modelClass!}(queryWrapper);
//${modelCode!}List.forEach(${modelCode!} -> {
// ${modelCode!}.setTypeName(DictCache.getValue(DictEnum.YES_NO, ${modelClass!}.getType()));
//});
return ${modelCode!}List;
}
}
@@ -0,0 +1,70 @@
/**
* BladeX Commercial License Agreement
* Copyright (c) 2018-2099, https://bladex.cn. All rights reserved.
* <p>
* Use of this software is governed by the Commercial License Agreement
* obtained after purchasing a license from BladeX.
* <p>
* 1. This software is for development use only under a valid license
* from BladeX.
* <p>
* 2. Redistribution of this software's source code to any third party
* without a commercial license is strictly prohibited.
* <p>
* 3. Licensees may copyright their own code but cannot use segments
* from this software for such purposes. Copyright of this software
* remains with BladeX.
* <p>
* Using this software signifies agreement to this License, and the software
* must not be used for illegal purposes.
* <p>
* THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY. The author is
* not liable for any claims arising from secondary or illegal development.
* <p>
* Author: Chill Zhuang (bladejava@qq.com)
*/
package ${strutil.replace(package.Entity,"pojo.entity","wrapper")};
import org.springblade.core.mp.support.BaseEntityWrapper;
import org.springblade.core.tool.utils.BeanUtil;
import ${packageName!}.pojo.entity.${modelClass!}Entity;
import ${packageName!}.pojo.vo.${modelClass!}VO;
import java.util.Objects;
#if(templateType=="tree"){
import org.springblade.core.tool.node.ForestNodeMerger;
import java.util.List;
import java.util.stream.Collectors;
#}
/**
* ${codeName!} 包装类,返回视图层所需的字段
*
* @author ${author!}
* @since ${date!}
*/
public class ${modelClass!}Wrapper extends BaseEntityWrapper<${modelClass!}Entity, ${modelClass!}VO> {
public static ${modelClass!}Wrapper build() {
return new ${modelClass!}Wrapper();
}
@Override
public ${modelClass!}VO entityVO(${modelClass!}Entity ${modelCode!}) {
${modelClass!}VO ${modelCode!}VO = Objects.requireNonNull(BeanUtil.copyProperties(${modelCode!}, ${modelClass!}VO.class));
//User createUser = UserCache.getUser(${modelCode!}.getCreateUser());
//User updateUser = UserCache.getUser(${modelCode!}.getUpdateUser());
//${modelCode!}VO.setCreateUserName(createUser.getName());
//${modelCode!}VO.setUpdateUserName(updateUser.getName());
return ${modelCode!}VO;
}
#if(templateType=="tree"){
public List<${modelClass!}VO> treeNodeVO(List<${modelClass!}Entity> list) {
List<${modelClass!}VO> collect = list.stream().map(${modelCode!} -> BeanUtil.copyProperties(${modelCode!}, ${modelClass!}VO.class)).collect(Collectors.toList());
return ForestNodeMerger.merge(collect);
}
#}
}
@@ -0,0 +1,5 @@
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/bladex?useSSL=false&useUnicode=true&characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&tinyInt1isBit=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true
spring.datasource.username=root
spring.datasource.password=root
author=BladeX
@@ -0,0 +1,50 @@
import request from '@/axios';
export const getList = (current, size, params) => {
return request({
url: '/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,386 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:6px 18px">
<!-- 查询模块 -->
<el-form :inline="true" :model="query">
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="${x.jdbcComment!}:">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜 索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清 空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__header">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button v-if="this.permissionList.addBtn" type="primary" icon="el-icon-plus" @click="handleAdd">新 增</el-button>
<el-button v-if="this.permissionList.delBtn" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删 除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading"
@selection-change="selectionChange"
:data="data"
:height="height"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="220" align="center">
<template \#="{row}">
<el-button v-if="this.permissionList.viewBtn" type="primary" text icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button v-if="this.permissionList.editBtn" type="primary" text icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button v-if="this.permissionList.delBtn" type="primary" text icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<div class="avue-crud__pagination" style="width:100%">
<!-- 分页模块 -->
<el-pagination align="right"
background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title"
v-model="box"
width="50%"
:before-close="beforeClose"
append-to-body>
<el-form :disabled="view" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="tree"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<template \#footer>
<span v-if="!view" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" @click="box = false">取 消</el-button>
</span>
</template>
</el-dialog>
</div>
</basic-container>
</template>
<script>
import { getList, getDetail, add, update, remove } from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import { mapGetters } from "vuex";
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
import {getDictionary} from '@/api/system/dict';
#break;
#}
#}
export default {
data () {
return {
height: 0,
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page);
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.param_add, false),
viewBtn: this.validData(this.permission.param_view, false),
delBtn: this.validData(this.permission.param_delete, false),
editBtn: this.validData(this.permission.param_edit, false),
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init() {
this.height = this.setPx(document.body.clientHeight - 340);
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page);
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page);
},
handleSubmit() {
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd(){
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
this.form.${x.propertyName!} = this.form.${x.propertyName!}.toString();
#}
#}
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose (done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page);
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
@@ -0,0 +1,30 @@
export default {
expand: false,
index: true,
border: true,
selection: true,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
#}
#if(x.isForm==0){
display: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
},
#}
]
}
@@ -0,0 +1,50 @@
import request from '@/axios';
export const getList = (current, size, params) => {
return request({
url: '/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,414 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:6px 18px">
<!-- 查询模块 -->
<el-form :inline="true" :model="query">
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="${x.jdbcComment!}:">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜 索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清 空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__header">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button v-if="this.permissionList.addBtn" type="primary" icon="el-icon-plus" @click="handleAdd">新 增</el-button>
<el-button v-if="this.permissionList.delBtn" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删 除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading"
@selection-change="selectionChange"
:data="data"
:height="height"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="300" align="center">
<template \#="{row}">
<el-button v-if="this.permissionList.viewBtn" type="primary" text icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button v-if="this.permissionList.editBtn" type="primary" text icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button v-if="this.permissionList.delBtn" type="primary" text icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
<el-button type="primary" text icon="el-icon-setting" @click="handleDrawer(row)">子表配置</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<div class="avue-crud__pagination" style="width:100%">
<!-- 分页模块 -->
<el-pagination align="right"
background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title"
v-model="box"
width="50%"
:before-close="beforeClose"
append-to-body>
<el-form :disabled="view" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="tree"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<template \#footer>
<span v-if="!view" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" @click="box = false">取 消</el-button>
</span>
</template>
</el-dialog>
<el-drawer
title="子表操作"
append-to-body
size="60%"
v-model="drawer"
:direction="direction"
:before-close="handleDrawerClose">
<${subModel.modelClass!}Sub :mainId="${modelCode!}Id"></${subModel.modelClass!}Sub>
</el-drawer>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import ${subModel.modelClass!}Sub from "@/views/${serviceCode!}/${subModel.modelCode!}Sub.vue";
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
import {getDictionary} from '@/api/system/dict';
#break;
#}
#}
export default {
components:{
${subModel.modelClass!}Sub
},
data() {
return {
height: 0,
// 主键
${modelCode!}Id: '',
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否展示抽屉
drawer: false,
// 抽屉方向
direction: 'rtl',
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page);
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.param_add, false),
viewBtn: this.validData(this.permission.param_view, false),
delBtn: this.validData(this.permission.param_delete, false),
editBtn: this.validData(this.permission.param_edit, false),
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init() {
this.height = this.setPx(document.body.clientHeight - 340);
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page);
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page);
},
handleSubmit() {
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd() {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
this.form.${x.propertyName!} = this.form.${x.propertyName!}.toString();
#}
#}
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDrawer(row) {
this.${modelCode!}Id = row.id;
this.drawer = true;
},
handleDrawerClose(){
this.${modelCode!}Id = '';
this.drawer = false;
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose(done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page);
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.querySub;
let values = {
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
@@ -0,0 +1,30 @@
export default {
expand: false,
index: true,
border: true,
selection: true,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
#}
#if(x.isForm==0){
display: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
},
#}
]
}
@@ -0,0 +1,372 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:6px 18px">
<!-- 查询模块 -->
<el-form :inline="true" :model="query">
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="字段">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜 索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清 空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__header">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button type="primary" icon="el-icon-plus" @click="handleAdd">新 增</el-button>
<el-button type="danger" icon="el-icon-delete" @click="handleDelete" plain>删 除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading"
@selection-change="selectionChange"
:data="data"
:height="height"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="220" align="center">
<template \#="{row}">
<el-button type="primary" text icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button type="primary" text icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button type="primary" text icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<div class="avue-crud__pagination" style="width:100%">
<!-- 分页模块 -->
<el-pagination align="right"
background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title"
v-model="box"
width="50%"
:before-close="beforeClose"
append-to-body>
<el-form :disabled="view" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="tree"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<template \#footer>
<span v-if="!view" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" @click="box = false">取 消</el-button>
</span>
</template>
</el-dialog>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
import {getDictionary} from '@/api/system/dict';
#break;
#}
#}
export default {
props: {
mainId: {
type: String
},
},
data() {
return {
height: 0,
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
watch: {
'mainId'() {
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
}
},
computed: {
...mapGetters(["permission"]),
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init() {
this.height = this.setPx(document.body.clientHeight - 340);
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
handleSubmit() {
this.form.${subFkIdHump!} = this.mainId;
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd() {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
this.form.${x.propertyName!} = this.form.${x.propertyName!}.toString();
#}
#}
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose(done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
onLoad(page, params = {}) {
this.loading = true;
getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
@@ -0,0 +1,60 @@
import request from '@/axios';
export const getList = (current, size, params) => {
return request({
url: '/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const getTree = (tenantId) => {
return request({
url: '/${serviceName!}/${modelCode!}/tree',
method: 'get',
params: {
tenantId,
}
})
}
export const remove = (ids) => {
return request({
url: '/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,412 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:6px 18px">
<!-- 查询模块 -->
<el-form :inline="true" :model="query">
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="${x.jdbcComment!}:">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜 索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清 空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__header">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button v-if="this.permissionList.addBtn" type="primary" icon="el-icon-plus" @click="handleAdd">新 增</el-button>
<el-button v-if="this.permissionList.delBtn" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删 除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading"
@selection-change="selectionChange"
row-key="id"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
:data="data"
:height="height"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="220" align="center">
<template \#="{row}">
<el-button v-if="this.permissionList.viewBtn" type="primary" text icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button v-if="this.permissionList.editBtn" type="primary" text icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button v-if="this.permissionList.delBtn" type="primary" text icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<div class="avue-crud__pagination" style="width:100%">
<!-- 分页模块 -->
<el-pagination align="right"
background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</div>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title"
v-model="box"
width="50%"
:before-close="beforeClose"
append-to-body>
<el-form :disabled="view" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="title">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="title">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(templateType=="tree"&&x.propertyName==treePidHump){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-tree
:data="treeData"
v-model="form.${treePidHump!}"
placeholder="请选择${x.jdbcComment!}"
:props="defaultProps"
@node-click="handleNodeClick">
</el-tree>
</el-form-item>
#}else if(x.componentType=="tree"&&x.propertyName!=treePidHump){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.id"
:label="item.${treeName}"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="YYYY-MM-DD HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<template \#footer>
<span v-if="!view" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" @click="box = false">取 消</el-button>
</span>
</template>
</el-dialog>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, getTree, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {validatenull} from "@/utils/validate";
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
import {getDictionary} from '@/api/system/dict';
#break;
#}
#}
export default {
data () {
return {
height: 0,
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 树型默认配置
defaultProps: {
children: 'children',
label: '${treeName}'
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
// 父节点列表
treeData: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted () {
this.init();
this.onLoad(this.page);
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.param_add, false),
viewBtn: this.validData(this.permission.param_view, false),
delBtn: this.validData(this.permission.param_delete, false),
editBtn: this.validData(this.permission.param_edit, false),
};
},
ids () {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init () {
this.height = this.setPx(document.body.clientHeight - 340);
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
handleNodeClick(data) {
this.form.${treePidHump!} = data.${treeIdHump!};
},
searchHide () {
this.search = !this.search;
},
searchChange () {
this.onLoad(this.page);
},
searchReset () {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page);
},
handleSubmit () {
if (validatenull(this.form.${treePidHump!})) {
this.form.${treePidHump!} = 0;
}
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd () {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit (row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
this.form.${x.propertyName!} = this.form.${x.propertyName!}.toString();
#}
#}
});
},
handleView (row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDelete () {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel (row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose (done) {
done()
this.form = {};
this.view = false;
},
selectionChange (list) {
this.selectionList = list;
},
selectionClear () {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange (currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page);
},
sizeChange (pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page);
},
onLoad (page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
this.data = res.data.data;
this.loading = false;
getTree().then(res => {
this.treeData = res.data.data;
});
});
}
}
};
</script>
@@ -0,0 +1,30 @@
export default {
expand: false,
index: true,
border: true,
selection: true,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
#}
#if(x.isForm==0){
display: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
},
#}
]
}
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,371 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:5px">
<!-- 查询模块 -->
<el-form :inline="true" :size="option.size" :model="query">
<template>
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="字段">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
</template>
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__menu">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button v-if="this.permissionList.addBtn" :size="option.size" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
<el-button v-if="this.permissionList.delBtn" :size="option.size" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button :size="option.size" icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button :size="option.size" icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading" :size="option.size" @selection-change="selectionChange" :data="data"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="180" align="center">
<template slot-scope="{row}">
<el-button v-if="this.permissionList.viewBtn" :size="option.size" type="text" icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button v-if="this.permissionList.editBtn" :size="option.size" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button v-if="this.permissionList.delBtn" :size="option.size" type="text" icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<!-- 分页模块 -->
<el-pagination
align="right" background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title" :visible.sync="box" width="50%" :before-close="beforeClose" append-to-body>
<el-form :disabled="view" :size="option.size" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="tree"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<span v-if="!view" slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" :size="option.size" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" :size="option.size" @click="box = false">取 消</el-button>
</span>
</el-dialog>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {getDictionary} from '@/api/system/dict'
export default {
data() {
return {
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page);
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.param_add, false),
viewBtn: this.validData(this.permission.param_view, false),
delBtn: this.validData(this.permission.param_delete, false),
editBtn: this.validData(this.permission.param_edit, false),
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page);
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page);
},
handleSubmit() {
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd() {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose(done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page);
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
<style lang="scss" scoped>
.el-pagination {
margin-top: 20px;
}
</style>
@@ -0,0 +1,31 @@
export default {
size: 'small',
expand: false,
index: true,
border: true,
selection: true,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "yyyy-MM-dd hh:mm:ss",
valueFormat: "yyyy-MM-dd hh:mm:ss",
#}
#if(x.isForm==0){
display: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
},
#}
]
}
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,399 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:5px">
<!-- 查询模块 -->
<el-form :inline="true" :size="option.size" :model="query">
<template>
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="字段">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
</template>
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__menu">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button v-if="this.permissionList.addBtn" :size="option.size" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
<el-button v-if="this.permissionList.delBtn" :size="option.size" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button :size="option.size" icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button :size="option.size" icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading" :size="option.size" @selection-change="selectionChange" :data="data"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="300" align="center">
<template slot-scope="{row}">
<el-button v-if="this.permissionList.viewBtn" :size="option.size" type="text" icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button v-if="this.permissionList.editBtn" :size="option.size" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button v-if="this.permissionList.delBtn" :size="option.size" type="text" icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
<el-button :size="option.size" type="text" icon="el-icon-setting" @click="handleDrawer(row)">子表配置</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<!-- 分页模块 -->
<el-pagination
align="right" background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title" :visible.sync="box" width="50%" :before-close="beforeClose" append-to-body>
<el-form :disabled="view" :size="option.size" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="tree"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<span v-if="!view" slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" :size="option.size" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" :size="option.size" @click="box = false">取 消</el-button>
</span>
</el-dialog>
<el-drawer
title="子表操作"
append-to-body
size="60%"
:visible.sync="drawer"
:direction="direction"
:before-close="handleDrawerClose">
<${subModel.modelClass!}Sub :mainId="${modelCode!}Id"></${subModel.modelClass!}Sub>
</el-drawer>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {getDictionary} from '@/api/system/dict'
import ${subModel.modelClass!}Sub from "@/views/${serviceCode!}/${subModel.modelCode!}Sub";
export default {
components:{
${subModel.modelClass!}Sub
},
data() {
return {
// 主键
${modelCode!}Id: '',
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否展示抽屉
drawer: false,
// 抽屉方向
direction: 'rtl',
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page);
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.param_add, false),
viewBtn: this.validData(this.permission.param_view, false),
delBtn: this.validData(this.permission.param_delete, false),
editBtn: this.validData(this.permission.param_edit, false),
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page);
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page);
},
handleSubmit() {
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd() {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDrawer(row) {
this.${modelCode!}Id = row.id;
this.drawer = true;
},
handleDrawerClose(){
this.${modelCode!}Id = '';
this.drawer = false;
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose(done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page);
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.querySub;
let values = {
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
<style lang="scss" scoped>
.el-pagination {
margin-top: 20px;
}
</style>
@@ -0,0 +1,31 @@
export default {
size: 'small',
expand: false,
index: true,
border: true,
selection: true,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "yyyy-MM-dd hh:mm:ss",
valueFormat: "yyyy-MM-dd hh:mm:ss",
#}
#if(x.isForm==0){
display: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
},
#}
]
}
@@ -0,0 +1,358 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:5px">
<!-- 查询模块 -->
<el-form :inline="true" :size="option.size" :model="query">
<template>
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="字段">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
</template>
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__menu">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button :size="option.size" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
<el-button :size="option.size" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删除
</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button :size="option.size" icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button :size="option.size" icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading" :size="option.size" @selection-change="selectionChange" :data="data"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="180" align="center">
<template slot-scope="{row}">
<el-button :size="option.size" type="text" icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button :size="option.size" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button :size="option.size" type="text" icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<el-row>
<!-- 分页模块 -->
<el-pagination
align="right" background
@size-change="sizeChange"
@current-change="currentChange"
:current-page="page.currentPage"
:page-sizes="[10, 20, 30, 40, 50, 100]"
:page-size="page.pageSize"
layout="total, sizes, prev, pager, next, jumper"
:total="page.total">
</el-pagination>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title" :visible.sync="box" width="50%" :before-close="beforeClose" append-to-body>
<el-form :disabled="view" :size="option.size" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="tree"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<span v-if="!view" slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" :size="option.size" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" :size="option.size" @click="box = false">取 消</el-button>
</span>
</el-dialog>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {getDictionary} from '@/api/system/dict'
export default {
props: {
mainId: {
type: String
},
},
data() {
return {
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
computed: {
...mapGetters(["permission"]),
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
watch: {
'mainId'() {
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
}
},
methods: {
init() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
handleSubmit() {
this.form.${subFkIdHump!} = this.mainId;
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd() {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose(done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page, {${subFkIdHump!}: this.mainId});
},
onLoad(page, params = {}) {
this.loading = true;
getList(page.currentPage, page.pageSize, Object.assign(params, this.query)).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
<style lang="scss" scoped>
.el-pagination {
margin-top: 20px;
}
</style>
@@ -0,0 +1,60 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const getTree = (tenantId) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/tree',
method: 'get',
params: {
tenantId,
}
})
}
export const remove = (ids) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,376 @@
<template>
<basic-container>
<div class="avue-crud">
<el-row :hidden="!search" style="padding:5px">
<!-- 查询模块 -->
<el-form :inline="true" :size="option.size" :model="query">
<template>
#for(x in prototypes) {
#if(x.isQuery==1){
<el-form-item label="字段">
<el-input v-model="query.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"></el-input>
</el-form-item>
#}
#}
</template>
<!-- 查询按钮 -->
<el-form-item>
<el-button type="primary" icon="el-icon-search" @click="searchChange">搜索</el-button>
<el-button icon="el-icon-delete" @click="searchReset()">清空</el-button>
</el-form-item>
</el-form>
</el-row>
<el-row>
<div class="avue-crud__menu">
<!-- 头部左侧按钮模块 -->
<div class="avue-crud__left">
<el-button v-if="this.permissionList.addBtn" :size="option.size" type="primary" icon="el-icon-plus" @click="handleAdd">新增</el-button>
<el-button v-if="this.permissionList.delBtn" :size="option.size" type="danger" icon="el-icon-delete" @click="handleDelete" plain>删除</el-button>
</div>
<!-- 头部右侧按钮模块 -->
<div class="avue-crud__right">
<el-button :size="option.size" icon="el-icon-refresh" @click="searchChange" circle></el-button>
<el-button :size="option.size" icon="el-icon-search" @click="searchHide" circle></el-button>
</div>
</div>
</el-row>
<el-row>
<!-- 列表模块 -->
<el-table ref="table" v-loading="loading" :size="option.size" @selection-change="selectionChange" :data="data"
row-key="id"
:tree-props="{children: 'children', hasChildren: 'hasChildren'}"
style="width: 100%"
:border="option.border">
<el-table-column type="selection" v-if="option.selection" width="55" align="center"></el-table-column>
<el-table-column type="expand" v-if="option.expand" align="center"></el-table-column>
<el-table-column v-if="option.index" label="\#" type="index" width="50" align="center">
</el-table-column>
<template v-for="(item,index) in option.column">
<!-- table字段 -->
<el-table-column v-if="item.hide!==true"
:prop="item.prop"
:label="item.label"
:width="item.width"
:key="index">
</el-table-column>
</template>
<!-- 操作栏模块 -->
<el-table-column prop="menu" label="操作" :width="180" align="center">
<template slot-scope="{row}">
<el-button v-if="this.permissionList.viewBtn" :size="option.size" type="text" icon="el-icon-view" @click="handleView(row)">查看</el-button>
<el-button v-if="this.permissionList.editBtn" :size="option.size" type="text" icon="el-icon-edit" @click="handleEdit(row)">编辑</el-button>
<el-button v-if="this.permissionList.delBtn" :size="option.size" type="text" icon="el-icon-delete" @click="rowDel(row)">删除</el-button>
</template>
</el-table-column>
</el-table>
</el-row>
<!-- 表单模块 -->
<el-dialog :title="title" :visible.sync="box" width="50%" :before-close="beforeClose" append-to-body>
<el-form :disabled="view" :size="option.size" ref="form" :model="form" label-width="80px">
<!-- 表单字段 -->
#for(x in prototypes) {
#if(x.isForm!=0){
#if(x.componentType=="input"){
<el-form-item label="${x.jdbcComment!}" prop="title">
<el-input v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="textarea"){
<el-form-item label="${x.jdbcComment!}" prop="title">
<el-input type="textarea" :rows="5" v-model="form.${x.propertyName!}" placeholder="请输入${x.jdbcComment!}"/>
</el-form-item>
#}else if(x.componentType=="select"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.dictKey"
:label="item.dictValue"
:value="item.dictKey">
</el-option>
</el-select>
</el-form-item>
#}else if(templateType=="tree"&&x.propertyName==treePidHump){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-tree
:data="treeData"
v-model="form.${treePidHump!}"
placeholder="请选择${x.jdbcComment!}"
:props="defaultProps"
@node-click="handleNodeClick">
</el-tree>
</el-form-item>
#}else if(x.componentType=="tree"&&x.propertyName!=treePidHump){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-select v-model="form.${x.propertyName!}" clearable placeholder="请选择${x.jdbcComment!}">
<el-option
v-for="item in ${x.propertyName!}Data"
:key="item.id"
:label="item.${treeName}"
:value="item.id">
</el-option>
</el-select>
</el-form-item>
#}else if(x.componentType=="radio"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-radio-group v-model="form.${x.propertyName!}">
<el-radio v-for="(item,index) in ${x.propertyName!}Data" :key="index" :label="item.dictKey">
{{item.dictValue}}
</el-radio>
</el-radio-group>
</el-form-item>
#}else if(x.componentType=="checkbox"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-checkbox-group v-model="form.${x.propertyName!}">
<el-checkbox v-for="(item,index) in ${x.propertyName!}Data" :label="item.dictValue" :key="index">{{item.dictValue}}</el-checkbox>
</el-checkbox-group>
</el-form-item>
#}else if(x.componentType=="switch"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-switch v-model="form.${x.propertyName!}" </el-switch>
</el-form-item>
#}else if(x.componentType=="date"){
<el-form-item label="${x.jdbcComment!}" prop="${x.propertyName!}">
<el-date-picker v-model="form.${x.propertyName!}" type="datetime" value-format="yyyy-MM-dd HH:mm:ss" placeholder="请选择${x.jdbcComment!}"></el-date-picker>
</el-form-item>
#}
#}
#}
</el-form>
<!-- 表单按钮 -->
<span v-if="!view" slot="footer" class="dialog-footer">
<el-button type="primary" icon="el-icon-circle-check" :size="option.size" @click="handleSubmit">提 交</el-button>
<el-button icon="el-icon-circle-close" :size="option.size" @click="box = false">取 消</el-button>
</span>
</el-dialog>
</div>
</basic-container>
</template>
<script>
import {getList, getDetail, getTree, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {getDictionary} from '@/api/system/dict';
import {mapGetters} from "vuex";
import {validatenull} from "@/util/validate";
export default {
data() {
return {
// 弹框标题
title: '',
// 是否展示弹框
box: false,
// 是否显示查询
search: true,
// 加载中
loading: true,
// 是否为查看模式
view: false,
// 查询信息
query: {},
// 分页信息
page: {
currentPage: 1,
pageSize: 10,
total: 40
},
// 树型默认配置
defaultProps: {
children: 'children',
label: '${treeName}'
},
// 表单数据
form: {},
// 选择行
selectionList: [],
// 表单配置
option: option,
// 表单列表
data: [],
// 父节点列表
treeData: [],
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
// ${x.jdbcComment!}字典数据
${x.propertyName!}Data: [],
#}
#}
}
},
mounted() {
this.init();
this.onLoad(this.page);
},
computed: {
...mapGetters(["permission"]),
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
init() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
getDictionary({code: '${x.dictCode!}'}).then(res => {
this.${x.propertyName!}Data = res.data.data;
});
#}
#}
},
handleNodeClick(data) {
this.form.${treePidHump!} = data.${treeIdHump!};
},
searchHide() {
this.search = !this.search;
},
searchChange() {
this.onLoad(this.page);
},
searchReset() {
this.query = {};
this.page.currentPage = 1;
this.onLoad(this.page);
},
handleSubmit() {
if (validatenull(this.form.${treePidHump!})) {
this.form.${treePidHump!} = 0;
}
if (!this.form.id) {
add(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
} else {
update(this.form).then(() => {
this.box = false;
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
})
}
},
handleAdd() {
this.title = '新增'
this.form = {}
this.box = true
},
handleEdit(row) {
this.title = '编辑'
this.box = true
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleView(row) {
this.title = '查看'
this.view = true;
this.box = true;
getDetail(row.id).then(res => {
this.form = res.data.data;
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.selectionClear();
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
beforeClose(done) {
done()
this.form = {};
this.view = false;
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.table.clearSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
this.onLoad(this.page);
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
this.onLoad(this.page);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
this.data = res.data.data;
this.loading = false;
getTree().then(res => {
this.treeData = res.data.data;
});
});
}
}
};
</script>
<style lang="scss" scoped>
.el-pagination {
margin-top: 20px;
}
</style>
@@ -0,0 +1,31 @@
export default {
size: 'small',
expand: false,
index: true,
border: true,
selection: true,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "yyyy-MM-dd hh:mm:ss",
valueFormat: "yyyy-MM-dd hh:mm:ss",
#}
#if(x.isForm==0){
display: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
},
#}
]
}
@@ -0,0 +1,90 @@
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
:showOkBtn="!isDetail"
:width="900"
>
<div v-show="isDetail">
<Description size="middle" @register="registerDetail" :column="2"/>
</div>
<div v-show="!isDetail">
<BasicForm @register="registerForm" />
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form/index';
import { formSchema, detailSchema } from './${modelCode!}.data';
import { getDetail, submitObj } from '@/api/${serviceCode!}/${modelCode!}';
import { Description, useDescription } from '@/components/Description/index';
const emit = defineEmits(['success']);
const isDetail = ref(true);
const isUpdate = ref(true);
const rowId = ref('');
//详情
const [registerDetail, { setDescProps }] = useDescription({
schema: detailSchema,
});
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {
span: 12,
},
actionColOptions: {
span: 23,
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !!data?.isDetail;
if (unref(isDetail)) {
const detail = await getDetail({ id: data.record.id });
setDescProps({
data: detail,
});
} else {
if (unref(isUpdate)) {
rowId.value = data.record.id;
const detailData = await getDetail({ id: data.record.id });
setFieldsValue({
...detailData,
});
}
}
});
const getTitle = computed(() => {
if (unref(isDetail)) {
return '查看';
} else {
return !unref(isUpdate) ? '新增' : '编辑';
}
});
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
if (unref(isUpdate)) {
values.id = rowId.value;
}
await submitObj(values);
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
@@ -0,0 +1,102 @@
import { BasicColumn } from '@/components/Table';
import { FormSchema } from '@/components/Table';
import { DescItem } from '@/components/Description/index';
import { getDictList } from '@/api/system/system';
export const columns: BasicColumn[] = [
#for(x in prototypes) {
#if(x.isList==1){
{
title: "${x.jdbcComment!}",
dataIndex: "${x.propertyName!}",
},
#}
#}
];
export const searchFormSchema: FormSchema[] = [
#for(x in prototypes) {
#if(x.isQuery==1){
{
field: "${x.propertyName!}_${x.queryType!}",
label: "${x.jdbcComment!}",
#if(x.componentType=="input"){
component: 'Input',
#}else if(x.componentType=="textarea"){
component: 'InputTextArea',
#}else if(x.componentType=="select"){
component: 'ApiSelect',
#}else if(x.componentType=="tree"){
component: 'ApiTreeSelect',
#}else if(x.componentType=="radio"){
component: 'RadioGroup',
#}else if(x.componentType=="checkbox"){
component: 'Checkbox',
#}else if(x.componentType=="switch"){
component: 'Switch',
#}else if(x.componentType=="date"){
component: 'DatePicker',
#}
#if(x.componentType=="select"&&x.dictCode!=null){
componentProps: {
api: getDictList,
params: { code: '${x.dictCode!}' },
labelField: 'dictValue',
valueField: 'dictKey',
},
#}
},
#}
#}
];
export const formSchema: FormSchema[] = [
#for(x in prototypes) {
#if(x.isForm!=0){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
#if(x.componentType=="input"){
component: 'Input',
#}else if(x.componentType=="textarea"){
component: 'InputTextArea',
#}else if(x.componentType=="select"){
component: 'ApiSelect',
#}else if(x.componentType=="tree"){
component: 'ApiTreeSelect',
#}else if(x.componentType=="radio"){
component: 'RadioGroup',
#}else if(x.componentType=="checkbox"){
component: 'Checkbox',
#}else if(x.componentType=="switch"){
component: 'Switch',
#}else if(x.componentType=="date"){
component: 'DatePicker',
#}
#if(x.componentType=="select"&&x.dictCode!=null){
componentProps: {
api: getDictList,
params: { code: '${x.dictCode!}' },
labelField: 'dictValue',
valueField: 'dictKey',
},
#}
#if(x.isRequired==1){
required: true,
#}
},
#}
#}
];
export const detailSchema: DescItem[] = [
#for(x in prototypes) {
#if(x.isForm!=0){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
},
#}
#}
];
@@ -0,0 +1,30 @@
import { defHttp } from '@/utils/http/axios';
enum Api {
List = '/${serviceName!}/${modelCode!}/list',
Submit = '/${serviceName!}/${modelCode!}/submit',
Detail = '/${serviceName!}/${modelCode!}/detail',
Remove = '/${serviceName!}/${modelCode!}/remove',
}
//列表
export function getList(params?: object) {
return defHttp.get({ url: Api.List, params: params },
{ joinParamsToUrl: true, joinTime: false });
}
//提交
export function submitObj(params?: object) {
return defHttp.post({ url: Api.Submit, params: params });
}
//详情
export function getDetail(params?: object) {
return defHttp.get({ url: Api.Detail, params });
}
//删除
export function remove(params?: object) {
return defHttp.post({ url: Api.Remove, params }, { joinParamsToUrl: true });
}
@@ -0,0 +1,124 @@
<template>
<div>
<BasicTable @register="registerTable">
<template \#toolbar>
<a-button type="primary" v-auth="'${modelCode!}_add'" @click="handleCreate">
新增
</a-button>
</template>
<template \#bodyCell="{ column, record }">
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
<template v-if="column.dataIndex === '${x.propertyName!}'">
{{ formatDictValue(options['${x.propertyName!}Data'], record.${x.propertyName!}) }}
</template>
#}
#}
<template v-if="column.dataIndex === 'action'">
<TableAction
:actions="[
{
auth: '${modelCode!}_view',
label: '查看',
color: 'success',
icon: 'clarity:info-standard-line',
onClick: handleView.bind(null, record),
},
{
auth: '${modelCode!}_edit',
label: '编辑',
icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
},
{
auth: '${modelCode!}_delete',
label: '删除',
icon: 'ant-design:delete-outlined',
color: 'error',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<${modelClass!}Modal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup name="${modelClass!}">
import { ref } from 'vue';
import ${modelClass!}Modal from './${modelClass!}Modal.vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getList, remove } from '@/api/${serviceCode!}/${modelCode!}';
import { useModal } from '@/components/Modal';
import { columns, searchFormSchema } from './${modelCode!}.data';
import { useMessage } from '@/hooks/web/useMessage';
import { formatDictValue } from '/@/utils';
import { getDictList } from '@/api/system/system';
//初始化字典
let options = ref({});
async function fetch() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
options.value['${x.propertyName!}Data'] = await getDictList({ code: '${x.dictCode!}' });
#}
#}
}
fetch();
const { createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload }] = useTable({
api: getList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
baseColProps: { xl: 12, xxl: 8 },
},
useSearchForm: true,
actionColumn: {
width: 250,
title: '操作',
dataIndex: 'action',
},
});
function handleCreate() {
openModal(true, {
isDetail: false,
isUpdate: false,
});
}
function handleView(record: Recordable) {
openModal(true, {
record,
isUpdate: false,
isDetail: true,
});
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
isDetail: false,
isUpdate: true,
});
}
async function handleDelete(record: Recordable) {
await remove({ ids: record.id });
createMessage.success('操作成功');
reload();
}
function handleSuccess() {
//操作成功提示
createMessage.success('操作成功');
reload();
}
</script>
@@ -0,0 +1,90 @@
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
:showOkBtn="!isDetail"
:width="900"
>
<div v-show="isDetail">
<Description size="middle" @register="registerDetail" :column="2"/>
</div>
<div v-show="!isDetail">
<BasicForm @register="registerForm" />
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form/index';
import { formSchema, detailSchema } from './${modelCode!}.data';
import { getDetail, submitObj } from '@/api/${serviceCode!}/${modelCode!}';
import { Description, useDescription } from '@/components/Description/index';
const emit = defineEmits(['success']);
const isDetail = ref(true);
const isUpdate = ref(true);
const rowId = ref('');
//详情
const [registerDetail, { setDescProps }] = useDescription({
schema: detailSchema,
});
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {
span: 12,
},
actionColOptions: {
span: 23,
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !!data?.isDetail;
if (unref(isDetail)) {
const detail = await getDetail({ id: data.record.id });
setDescProps({
data: detail,
});
} else {
if (unref(isUpdate)) {
rowId.value = data.record.id;
const detailData = await getDetail({ id: data.record.id });
setFieldsValue({
...detailData,
});
}
}
});
const getTitle = computed(() => {
if (unref(isDetail)) {
return '查看';
} else {
return !unref(isUpdate) ? '新增' : '编辑';
}
});
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
if (unref(isUpdate)) {
values.id = rowId.value;
}
await submitObj(values);
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
@@ -0,0 +1,102 @@
import { BasicColumn } from '@/components/Table';
import { FormSchema } from '@/components/Table';
import { DescItem } from '@/components/Description/index';
import { getDictList } from '@/api/system/system';
export const columns: BasicColumn[] = [
#for(x in prototypes) {
#if(x.isList==1){
{
title: "${x.jdbcComment!}",
dataIndex: "${x.propertyName!}",
},
#}
#}
];
export const searchFormSchema: FormSchema[] = [
#for(x in prototypes) {
#if(x.isQuery==1){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
#if(x.componentType=="input"){
component: 'Input',
#}else if(x.componentType=="textarea"){
component: 'InputTextArea',
#}else if(x.componentType=="select"){
component: 'ApiSelect',
#}else if(x.componentType=="tree"){
component: 'ApiTreeSelect',
#}else if(x.componentType=="radio"){
component: 'RadioGroup',
#}else if(x.componentType=="checkbox"){
component: 'Checkbox',
#}else if(x.componentType=="switch"){
component: 'Switch',
#}else if(x.componentType=="date"){
component: 'DatePicker',
#}
#if(x.componentType=="select"&&x.dictCode!=null){
componentProps: {
api: getDictList,
params: { code: '${x.dictCode!}' },
labelField: 'dictValue',
valueField: 'dictKey',
},
#}
},
#}
#}
];
export const formSchema: FormSchema[] = [
#for(x in prototypes) {
#if(x.isForm!=0){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
#if(x.componentType=="input"){
component: 'Input',
#}else if(x.componentType=="textarea"){
component: 'InputTextArea',
#}else if(x.componentType=="select"){
component: 'ApiSelect',
#}else if(x.componentType=="tree"){
component: 'ApiTreeSelect',
#}else if(x.componentType=="radio"){
component: 'RadioGroup',
#}else if(x.componentType=="checkbox"){
component: 'Checkbox',
#}else if(x.componentType=="switch"){
component: 'Switch',
#}else if(x.componentType=="date"){
component: 'DatePicker',
#}
#if(x.componentType=="select"&&x.dictCode!=null){
componentProps: {
api: getDictList,
params: { code: '${x.dictCode!}' },
labelField: 'dictValue',
valueField: 'dictKey',
},
#}
#if(x.isRequired==1){
required: true,
#}
},
#}
#}
];
export const detailSchema: DescItem[] = [
#for(x in prototypes) {
#if(x.isForm!=0){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
},
#}
#}
];
@@ -0,0 +1,30 @@
import { defHttp } from '@/utils/http/axios';
enum Api {
List = '/${serviceName!}/${modelCode!}/list',
Submit = '/${serviceName!}/${modelCode!}/submit',
Detail = '/${serviceName!}/${modelCode!}/detail',
Remove = '/${serviceName!}/${modelCode!}/remove',
}
//列表
export function getList(params?: object) {
return defHttp.get({ url: Api.List, params: params },
{ joinParamsToUrl: true, joinTime: false });
}
//提交
export function submitObj(params?: object) {
return defHttp.post({ url: Api.Submit, params: params });
}
//详情
export function getDetail(params?: object) {
return defHttp.get({ url: Api.Detail, params });
}
//删除
export function remove(params?: object) {
return defHttp.post({ url: Api.Remove, params }, { joinParamsToUrl: true });
}
@@ -0,0 +1,143 @@
<template>
<div>
<BasicTable @register="registerTable">
<template \#toolbar>
<a-button type="primary" v-auth="'${modelCode!}_add'" @click="handleCreate">
新增
</a-button>
</template>
<template \#bodyCell="{ column, record }">
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
<template v-if="column.dataIndex === '${x.propertyName!}'">
{{ formatDictValue(options['${x.propertyName!}Data'], record.${x.propertyName!}) }}
</template>
#}
#}
<template v-if="column.dataIndex === 'action'">
<TableAction
:actions="[
{
auth: '${modelCode!}_view',
label: '查看',
color: 'success',
icon: 'clarity:info-standard-line',
onClick: handleView.bind(null, record),
},
{
auth: '${modelCode!}_edit',
label: '编辑',
icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
},
{
label: '子表配置',
icon: 'clarity:note-edit-line',
onClick: handleSubConfig.bind(null, record),
},
{
auth: '${modelCode!}_delete',
label: '删除',
icon: 'ant-design:delete-outlined',
color: 'error',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<${modelClass!}Modal @register="registerModal" @success="handleSuccess" />
<${subModel.modelClass!}Sub @register="registerDrawer" />
</div>
</template>
<script lang="ts" setup name="${modelClass!}">
import { ref } from 'vue';
import ${modelClass!}Modal from './${modelClass!}Modal.vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getList, remove } from '/@/api/${serviceCode!}/${modelCode!}';
import { useModal } from '@/components/Modal';
import { useDrawer } from '@/components/Drawer';
import ${subModel.modelClass!}Sub from './${subModel.modelClass!}Sub.vue';
import { columns, searchFormSchema } from './${modelCode!}.data';
import { useMessage } from '@/hooks/web/useMessage';
import { formatDictValue } from '@/utils';
import { getDictList } from '@/api/system/system';
//初始化字典
let options = ref({});
async function fetch() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
options.value['${x.propertyName!}Data'] = await getDictList({ code: '${x.dictCode!}' });
#}
#}
}
fetch();
const { createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerDrawer, { openDrawer }] = useDrawer();
const [registerTable, { reload }] = useTable({
api: getList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
baseColProps: { xl: 12, xxl: 8 },
},
useSearchForm: true,
actionColumn: {
width: 250,
title: '操作',
dataIndex: 'action',
},
});
function handleCreate() {
openModal(true, {
isDetail: false,
isUpdate: false,
});
}
function handleView(record: Recordable) {
openModal(true, {
record,
isUpdate: false,
isDetail: true,
});
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
isDetail: false,
isUpdate: true,
});
}
function handleSubConfig(record: Recordable) {
openDrawer(true, {
mainId:record.id
});
}
async function handleDelete(record: Recordable) {
await remove({ ids: record.id });
createMessage.success('操作成功');
reload();
}
function handleSuccess() {
//操作成功提示
createMessage.success('操作成功');
reload();
}
</script>
@@ -0,0 +1,113 @@
<template>
<BasicDrawer
v-bind="$attrs"
@register="registerDrawer"
:title="`[\${${model.modelCode!}Name}] 配置`"
width="1000px"
>
<BasicTable @register="registerTable">
<template \#toolbar>
<a-button type="primary" @click="handleCreate">新增</a-button>
</template>
<template \#bodyCell="{ column, record }">
<template v-if="column.dataIndex === 'action'">
<TableAction
:actions="[
{
label: '查看',
color: 'success',
icon: 'clarity:info-standard-line',
onClick: handleView.bind(null, record),
},
{
label: '编辑',
icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
},
{
label: '删除',
icon: 'ant-design:delete-outlined',
color: 'error',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<${modelClass!}Modal @register="registerModal" @success="handleSuccess" />
</BasicDrawer>
</template>
<script lang="ts" setup>
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { BasicDrawer, useDrawerInner } from '@/components/Drawer';
import { getList, remove } from '@/api/${serviceCode!}/${modelCode!}';
import { columns, searchFormSchema } from './${modelCode!}.data';
import { useModal } from '@/components/Modal';
import ${modelClass!}Modal from './${modelClass!}Modal.vue';
import { useMessage } from '@/hooks/web/useMessage';
const { createMessage } = useMessage();
const { success } = createMessage;
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload, setProps }] = useTable({
api: getList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
baseColProps: { xl: 12, xxl: 6 },
},
useSearchForm: true,
immediate: false,
actionColumn: {
width: 250,
title: '操作',
dataIndex: 'action',
},
});
const [registerDrawer, { setDrawerProps }] = useDrawerInner(async (data) => {
setProps({
searchInfo: {${subFkIdHump!}: data.mainId},
});
reload();
});
function handleCreate() {
openModal(true, {
isUpdate: false,
isDetail: false,
});
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
isUpdate: true,
isDetail: false,
});
}
function handleView(record: Recordable) {
openModal(true, {
record,
isUpdate: false,
isDetail: true,
});
}
async function handleDelete(record: Recordable) {
await remove({ ids: record.id });
success('操作成功');
reload();
}
function handleSuccess() {
//操作成功提示
success('操作成功');
reload();
}
</script>
@@ -0,0 +1,90 @@
<template>
<BasicModal
v-bind="$attrs"
@register="registerModal"
:title="getTitle"
@ok="handleSubmit"
:showOkBtn="!isDetail"
:width="900"
>
<div v-show="isDetail">
<Description size="middle" @register="registerDetail" :column="2"/>
</div>
<div v-show="!isDetail">
<BasicForm @register="registerForm" />
</div>
</BasicModal>
</template>
<script lang="ts" setup>
import { ref, computed, unref } from 'vue';
import { BasicModal, useModalInner } from '@/components/Modal';
import { BasicForm, useForm } from '@/components/Form/index';
import { formSchema, detailSchema } from './${modelCode!}.data';
import { getDetail, submitObj } from '@/api/${serviceCode!}/${modelCode!}';
import { Description, useDescription } from '@/components/Description/index';
const emit = defineEmits(['success']);
const isDetail = ref(true);
const isUpdate = ref(true);
const rowId = ref('');
//详情
const [registerDetail, { setDescProps }] = useDescription({
schema: detailSchema,
});
const [registerForm, { setFieldsValue, resetFields, validate }] = useForm({
labelWidth: 100,
schemas: formSchema,
showActionButtonGroup: false,
baseColProps: {
span: 12,
},
actionColOptions: {
span: 23,
},
});
const [registerModal, { setModalProps, closeModal }] = useModalInner(async (data) => {
resetFields();
setModalProps({ confirmLoading: false });
isUpdate.value = !!data?.isUpdate;
isDetail.value = !!data?.isDetail;
if (unref(isDetail)) {
const detail = await getDetail({ id: data.record.id });
setDescProps({
data: detail,
});
} else {
if (unref(isUpdate)) {
rowId.value = data.record.id;
const detailData = await getDetail({ id: data.record.id });
setFieldsValue({
...detailData,
});
}
}
});
const getTitle = computed(() => {
if (unref(isDetail)) {
return '查看';
} else {
return !unref(isUpdate) ? '新增' : '编辑';
}
});
async function handleSubmit() {
try {
const values = await validate();
setModalProps({ confirmLoading: true });
if (unref(isUpdate)) {
values.id = rowId.value;
}
await submitObj(values);
closeModal();
emit('success', { isUpdate: unref(isUpdate), values: { ...values, id: rowId.value } });
} finally {
setModalProps({ confirmLoading: false });
}
}
</script>
@@ -0,0 +1,102 @@
import { BasicColumn } from '@/components/Table';
import { FormSchema } from '@/components/Table';
import { DescItem } from '@/components/Description/index';
import { getDictList } from '@/api/system/system';
export const columns: BasicColumn[] = [
#for(x in prototypes) {
#if(x.isList==1){
{
title: "${x.jdbcComment!}",
dataIndex: "${x.propertyName!}",
},
#}
#}
];
export const searchFormSchema: FormSchema[] = [
#for(x in prototypes) {
#if(x.isQuery==1){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
#if(x.componentType=="input"){
component: 'Input',
#}else if(x.componentType=="textarea"){
component: 'InputTextArea',
#}else if(x.componentType=="select"){
component: 'ApiSelect',
#}else if(x.componentType=="tree"){
component: 'ApiTreeSelect',
#}else if(x.componentType=="radio"){
component: 'RadioGroup',
#}else if(x.componentType=="checkbox"){
component: 'Checkbox',
#}else if(x.componentType=="switch"){
component: 'Switch',
#}else if(x.componentType=="date"){
component: 'DatePicker',
#}
#if(x.componentType=="select"&&x.dictCode!=null){
componentProps: {
api: getDictList,
params: { code: '${x.dictCode!}' },
labelField: 'dictValue',
valueField: 'dictKey',
},
#}
},
#}
#}
];
export const formSchema: FormSchema[] = [
#for(x in prototypes) {
#if(x.isForm!=0){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
#if(x.componentType=="input"){
component: 'Input',
#}else if(x.componentType=="textarea"){
component: 'InputTextArea',
#}else if(x.componentType=="select"){
component: 'ApiSelect',
#}else if(x.componentType=="tree"){
component: 'ApiTreeSelect',
#}else if(x.componentType=="radio"){
component: 'RadioGroup',
#}else if(x.componentType=="checkbox"){
component: 'Checkbox',
#}else if(x.componentType=="switch"){
component: 'Switch',
#}else if(x.componentType=="date"){
component: 'DatePicker',
#}
#if(x.componentType=="select"&&x.dictCode!=null){
componentProps: {
api: getDictList,
params: { code: '${x.dictCode!}' },
labelField: 'dictValue',
valueField: 'dictKey',
},
#}
#if(x.isRequired==1){
required: true,
#}
},
#}
#}
];
export const detailSchema: DescItem[] = [
#for(x in prototypes) {
#if(x.isForm!=0){
{
field: "${x.propertyName!}",
label: "${x.jdbcComment!}",
},
#}
#}
];
@@ -0,0 +1,30 @@
import { defHttp } from '@/utils/http/axios';
enum Api {
List = '/${serviceName!}/${modelCode!}/list',
Submit = '/${serviceName!}/${modelCode!}/submit',
Detail = '/${serviceName!}/${modelCode!}/detail',
Remove = '/${serviceName!}/${modelCode!}/remove',
}
//列表
export function getList(params?: object) {
return defHttp.get({ url: Api.List, params: params },
{ joinParamsToUrl: true, joinTime: false });
}
//提交
export function submitObj(params?: object) {
return defHttp.post({ url: Api.Submit, params: params });
}
//详情
export function getDetail(params?: object) {
return defHttp.get({ url: Api.Detail, params });
}
//删除
export function remove(params?: object) {
return defHttp.post({ url: Api.Remove, params }, { joinParamsToUrl: true });
}
@@ -0,0 +1,124 @@
<template>
<div>
<BasicTable @register="registerTable">
<template \#toolbar>
<a-button type="primary" v-auth="'${modelCode!}_add'" @click="handleCreate">
新增
</a-button>
</template>
<template \#bodyCell="{ column, record }">
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
<template v-if="column.dataIndex === '${x.propertyName!}'">
{{ formatDictValue(options['${x.propertyName!}Data'], record.category) }}
</template>
#}
#}
<template v-if="column.dataIndex === 'action'">
<TableAction
:actions="[
{
auth: '${modelCode!}_view',
label: '查看',
color: 'success',
icon: 'clarity:info-standard-line',
onClick: handleView.bind(null, record),
},
{
auth: '${modelCode!}_edit',
label: '编辑',
icon: 'clarity:note-edit-line',
onClick: handleEdit.bind(null, record),
},
{
auth: '${modelCode!}_delete',
label: '删除',
icon: 'ant-design:delete-outlined',
color: 'error',
popConfirm: {
title: '是否确认删除',
confirm: handleDelete.bind(null, record),
},
},
]"
/>
</template>
</template>
</BasicTable>
<${modelClass!}Modal @register="registerModal" @success="handleSuccess" />
</div>
</template>
<script lang="ts" setup name="${modelClass!}">
import { ref } from 'vue';
import ${modelClass!}Modal from './${modelCode!}Modal.vue';
import { BasicTable, useTable, TableAction } from '@/components/Table';
import { getList, remove } from '@/api/${serviceCode!}/${modelCode!}';
import { useModal } from '@/components/Modal';
import { columns, searchFormSchema } from './${modelCode!}.data';
import { useMessage } from '@/hooks/web/useMessage';
import { formatDictValue } from '@/utils';
import { getDictList } from '@/api/system/system';
//初始化字典
let options = ref({});
async function fetch() {
#for(x in prototypes) {
#if(isNotEmpty(x.dictCode)){
options.value['${x.propertyName!}Data'] = await getDictList({ code: '${x.dictCode!}' });
#}
#}
}
fetch();
const { createMessage } = useMessage();
const [registerModal, { openModal }] = useModal();
const [registerTable, { reload }] = useTable({
api: getList,
rowKey: 'id',
columns,
formConfig: {
labelWidth: 120,
schemas: searchFormSchema,
baseColProps: { xl: 12, xxl: 8 },
},
useSearchForm: true,
actionColumn: {
width: 250,
title: '操作',
dataIndex: 'action',
},
});
function handleCreate() {
openModal(true, {
isDetail: false,
isUpdate: false,
});
}
function handleView(record: Recordable) {
openModal(true, {
record,
isUpdate: false,
isDetail: true,
});
}
function handleEdit(record: Recordable) {
openModal(true, {
record,
isDetail: false,
isUpdate: true,
});
}
async function handleDelete(record: Recordable) {
await remove({ ids: record.id });
createMessage.success('操作成功');
reload();
}
function handleSuccess() {
//操作成功提示
createMessage.success('操作成功');
reload();
}
</script>
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,247 @@
<template>
<basic-container>
<avue-crud :option="option"
:search.sync="search"
:table-loading="loading"
:data="data"
:page.sync="page"
:permission="permissionList"
:before-open="beforeOpen"
v-model="form"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad">
<template slot="menuLeft">
<el-button type="danger"
size="small"
icon="el-icon-delete"
plain
v-if="permission.${modelCode!}_delete"
@click="handleDelete">删 除
</el-button>
<el-button type="warning"
size="small"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
</avue-crud>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {exportBlob} from "@/api/common";
import {getToken} from '@/util/auth';
import {downloadXls} from "@/util/util";
import {dateNow} from "@/util/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
form: {},
query: {},
search: {},
loading: true,
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
selectionList: [],
option: option,
data: []
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.vaildData(this.permission.${modelCode!}_add, false),
viewBtn: this.vaildData(this.permission.${modelCode!}_view, false),
delBtn: this.vaildData(this.permission.${modelCode!}_delete, false),
editBtn: this.vaildData(this.permission.${modelCode!}_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
rowSave(row, done, loading) {
add(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
window.console.log(error);
});
},
rowUpdate(row, index, done, loading) {
update(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
console.log(error);
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/api/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage){
this.page.currentPage = currentPage;
},
sizeChange(pageSize){
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
<style>
</style>
@@ -0,0 +1,67 @@
export default {
height:'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
viewBtn: true,
selection: true,
dialogClickModal: false,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"editor")){
component: 'AvueUeditor',
options: {
action: '/api/blade-resource/oss/endpoint/put-file',
props: {
res: "data",
url: "link",
}
},
hide: true,
minRows: 6,
#}else{
type: "${x.componentType!}",
#}
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "yyyy-MM-dd hh:mm:ss",
valueFormat: "yyyy-MM-dd hh:mm:ss",
#}
#if(isNotEmpty(x.dictCode)){
dicUrl: "/api/blade-system/dict/dictionary?code=${x.dictCode!}",
dataType: "number",
props: {
label: "dictValue",
value: "dictKey"
},
#}
#if(x.isForm==0){
addDisplay: false,
editDisplay: false,
viewDisplay: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
#if(x.isRequired==1){
rules: [{
required: true,
message: "请输入${x.jdbcComment!}",
trigger: "blur"
}],
#}
},
#}
]
}
@@ -0,0 +1,50 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,446 @@
<template>
<basic-container>
<avue-crud :option="option"
:search.sync="search"
:table-loading="loading"
:data="data"
:page.sync="page"
:permission="permissionList"
:before-open="beforeOpen"
v-model="form"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad">
<template slot="menuLeft">
<el-button type="danger"
size="small"
icon="el-icon-delete"
plain
v-if="permission.${model.modelCode!}_delete"
@click="handleDelete">删 除
</el-button>
<el-button type="warning"
size="small"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
<template slot-scope="{row}" slot="menu">
<el-button type="text"
icon="el-icon-setting"
size="small"
@click.stop="handleDataSub(row)">配 置
</el-button>
</template>
</avue-crud>
<el-drawer :title="`[\${${model.modelCode!}Name}] 配置`" :visible.sync="subVisible" :direction="direction" append-to-body
:before-close="handleSubClose" size="1000px">
<basic-container>
<avue-crud :option="optionSub"
:data="dataSub"
:page.sync="pageSub"
v-model="formSub"
:table-loading="loadingSub"
ref="crudSub"
@row-del="rowDelSub"
@row-update="rowUpdateSub"
@row-save="rowSaveSub"
:before-open="beforeOpenSub"
@search-change="searchChangeSub"
@search-reset="searchResetSub"
@selection-change="selectionChangeSub"
@current-change="currentChangeSub"
@size-change="sizeChangeSub"
@on-load="onLoadSub">
<template slot="menuLeft">
<el-button type="danger"
size="small"
icon="el-icon-delete"
plain
@click="handleDeleteSub">删 除
</el-button>
</template>
</avue-crud>
</basic-container>
</el-drawer>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${model.modelCode!}";
import {getList as getListSub, getDetail as getDetailSub, add as addSub, update as updateSub, remove as removeSub} from "@/api/${serviceCode!}/${subModel.modelCode!}";
import option from "@/option/${serviceCode!}/${model.modelCode!}";
import optionSub from "@/option/${serviceCode!}/${subModel.modelCode!}";
import {mapGetters} from "vuex";
import {exportBlob} from "@/api/common";
import {getToken} from '@/util/auth';
import {downloadXls} from "@/util/util";
import {dateNow} from "@/util/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
form: {},
query: {},
search: {},
loading: true,
data: [],
selectionList: [],
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
option: option,
subVisible: false,
direction: 'rtl',
${subFkIdHump!}: 0,
${model.modelCode!}Name: "${model.modelName!}",
formSub: {},
querySub: {},
loadingSub: true,
dataSub: [],
selectionListSub: [],
pageSub: {
pageSize: 10,
currentPage: 1,
total: 0
},
optionSub: optionSub
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.vaildData(this.permission.${model.modelCode!}_add, false),
viewBtn: this.vaildData(this.permission.${model.modelCode!}_view, false),
delBtn: this.vaildData(this.permission.${model.modelCode!}_delete, false),
editBtn: this.vaildData(this.permission.${model.modelCode!}_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
},
subIds() {
let ids = [];
this.selectionListSub.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
// 主表模块
rowSave(row, done, loading) {
add(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
window.console.log(error);
loading();
});
},
rowUpdate(row, index, done, loading) {
update(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
window.console.log(error);
loading();
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/api/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage){
this.page.currentPage = currentPage;
},
sizeChange(pageSize){
this.page.pageSize = pageSize;
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
},
// 子表模块
handleDataSub(row) {
this.subVisible = true;
this.${subFkIdHump!} = row.id;
this.onLoadSub(this.pageSub)
},
handleSubClose(hide) {
hide();
},
rowSaveSub(row, loading, done) {
row = {
...row,
${subFkIdHump!}: this.${subFkIdHump!},
};
addSub(row).then(() => {
loading();
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
}, error => {
done();
window.console.log(error);
});
},
rowUpdateSub(row, index, loading, done) {
row = {
...row,
${subFkIdHump!}: this.${subFkIdHump!},
};
updateSub(row).then(() => {
loading();
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
}, error => {
done();
window.console.log(error);
});
},
rowDelSub(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return removeSub(row.id);
})
.then(() => {
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDeleteSub() {
if (this.selectionListSub.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return removeSub(this.subIds);
})
.then(() => {
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crudSub.toggleSelection();
});
},
beforeOpenSub(done, type) {
if (["edit", "view"].includes(type)) {
getDetailSub(this.formSub.id).then(res => {
this.formSub = res.data.data;
});
}
done();
},
searchResetSub() {
this.querySub = {};
this.onLoadSub(this.pageSub);
},
searchChangeSub(params) {
this.querySub = params;
this.onLoadSub(this.pageSub, params);
},
selectionChangeSub(list) {
this.selectionListSub = list;
},
currentChangeSub(currentPage) {
this.pageSub.currentPage = currentPage;
},
sizeChangeSub(pageSize) {
this.pageSub.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoadSub(page, params = {}) {
this.loadingSub = true;
let values = {
${subFkIdHump!}: this.${subFkIdHump!},
}
const {
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.querySub;
values = {
...values,
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getListSub(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.pageSub.total = data.total;
this.dataSub = data.records;
this.selectionListSub = [];
this.loadingSub = false;
});
},
}
};
</script>
<style>
</style>
@@ -0,0 +1,67 @@
export default {
height:'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
viewBtn: true,
selection: true,
menuWidth: 300,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"editor")){
component: 'AvueUeditor',
options: {
action: '/api/blade-resource/oss/endpoint/put-file',
props: {
res: "data",
url: "link",
}
},
hide: true,
minRows: 6,
#}else{
type: "${x.componentType!}",
#}
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "yyyy-MM-dd hh:mm:ss",
valueFormat: "yyyy-MM-dd hh:mm:ss",
#}
#if(isNotEmpty(x.dictCode)){
dicUrl: "/api/blade-system/dict/dictionary?code=${x.dictCode!}",
dataType: "number",
props: {
label: "dictValue",
value: "dictKey"
},
#}
#if(x.isForm==0){
addDisplay: false,
editDisplay: false,
viewDisplay: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
#if(x.isRequired==1&&isEmpty(x.validateRule)){
rules: [{
required: true,
message: "请输入${x.jdbcComment!}",
trigger: "blur"
}],
#}
},
#}
]
}
@@ -0,0 +1,60 @@
import request from '@/router/axios';
export const getList = (current, size, params) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const getTree = (tenantId) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/tree',
method: 'get',
params: {
tenantId,
}
})
}
export const remove = (ids) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/api/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,248 @@
<template>
<basic-container>
<avue-crud :option="option"
:search.sync="search"
:table-loading="loading"
:data="data"
:page.sync="page"
:permission="permissionList"
:before-open="beforeOpen"
v-model="form"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad">
<template slot="menuLeft">
<el-button type="danger"
size="small"
icon="el-icon-delete"
plain
v-if="permission.${modelCode!}_delete"
@click="handleDelete">删 除
</el-button>
<el-button type="warning"
size="small"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
</avue-crud>
</basic-container>
</template>
<script>
import {getList, getDetail, getTree, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {exportBlob} from "@/api/common";
import {getToken} from '@/util/auth';
import {downloadXls} from "@/util/util";
import {dateNow} from "@/util/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
form: {},
query: {},
search: {},
loading: true,
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
selectionList: [],
option: option,
data: []
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.vaildData(this.permission.${modelCode!}_add, false),
viewBtn: this.vaildData(this.permission.${modelCode!}_view, false),
delBtn: this.vaildData(this.permission.${modelCode!}_delete, false),
editBtn: this.vaildData(this.permission.${modelCode!}_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
rowSave(row, done, loading) {
add(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
window.console.log(error);
});
},
rowUpdate(row, index, done, loading) {
update(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
console.log(error);
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/api/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage){
this.page.currentPage = currentPage;
},
sizeChange(pageSize){
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
this.data = res.data.data;
this.loading = false;
getTree().then(res => {
const column = this.findObject(this.option.column, "${treePidHump!}");
column.dicData = res.data.data;
});
});
}
}
};
</script>
<style>
</style>
@@ -0,0 +1,74 @@
export default {
height:'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
viewBtn: true,
selection: true,
dialogClickModal: false,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(x.propertyName==treePidHump){
type: "tree",
dicData: [],
props: {
label: "title",
},
value: 0,
#}else if(strutil.contain(x.componentType,"editor")){
component: 'AvueUeditor',
options: {
action: '/api/blade-resource/oss/endpoint/put-file',
props: {
res: "data",
url: "link",
}
},
hide: true,
minRows: 6,
#}else{
type: "${x.componentType!}",
#}
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "yyyy-MM-dd hh:mm:ss",
valueFormat: "yyyy-MM-dd hh:mm:ss",
#}
#if(isNotEmpty(x.dictCode)&&x.propertyName!=treePidHump){
dicUrl: "/api/blade-system/dict/dictionary?code=${x.dictCode!}",
dataType: "number",
props: {
label: "dictValue",
value: "dictKey"
},
#}
#if(x.isForm==0){
addDisplay: false,
editDisplay: false,
viewDisplay: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
#if(x.isRequired==1){
rules: [{
required: true,
message: "请输入${x.jdbcComment!}",
trigger: "blur"
}],
#}
},
#}
]
}
@@ -0,0 +1,50 @@
import request from '@/axios';
export const getList = (current, size, params) => {
return request({
url: '/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,258 @@
<template>
<basic-container>
<nf-crud
:option="option"
:table-loading="loading"
:data="data"
v-model:page="page"
:permission="permissionList"
:before-open="beforeOpen"
v-model="form"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad"
>
<template \#menu-left>
<el-button type="danger"
plain
icon="el-icon-delete"
v-if="permission[serviceName + '_delete']"
@click="handleDelete"
>
删 除
</el-button>
<el-button type="warning"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
</nf-crud>
</basic-container>
</template>
<script>
import { getList, getDetail, add, update, remove } from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import { mapGetters } from "vuex";
import { exportBlob } from "@/api/common";
import { getToken } from '@/utils/auth';
import { downloadXls } from "@/utils/util";
import { dateNow } from "@/utils/date";
import { loadFormModule } from '@/utils/module';
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
serviceName: "${modelCode!}",
form: {},
query: {},
loading: true,
page: {
pageSize: 10,
currentPage: 1,
total: 0,
},
selectionList: [],
option: option,
data: [],
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(
this.permission[this.serviceName + "_add"],
false,
),
viewBtn: this.validData(
this.permission[this.serviceName + "_view"],
false,
),
delBtn: this.validData(
this.permission[this.serviceName + "_delete"],
false,
),
editBtn: this.validData(
this.permission[this.serviceName + "_edit"],
false,
),
};
},
ids() {
let ids = [];
this.selectionList.forEach((ele) => {
ids.push(ele.id);
});
return ids.join(",");
},
},
created() {
loadFormModule(this.$app);
},
methods: {
rowSave(row, done) {
add(row).then(
() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!",
});
done();
},
(error) => {
done();
console.log(error);
},
);
},
rowUpdate(row, index, done) {
update(row).then(
() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!",
});
done();
},
(error) => {
done();
console.log(error);
},
);
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!",
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning",
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!",
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then((res) => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage) {
this.page.currentPage = currentPage;
},
sizeChange(pageSize) {
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
getList(
page.currentPage,
page.pageSize,
Object.assign(params, this.query),
).then((res) => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
},
},
};
</script>
<style></style>
@@ -0,0 +1,245 @@
<template>
<basic-container>
<avue-crud :option="option"
v-model:search="search"
v-model:page="page"
v-model="form"
:table-loading="loading"
:data="data"
:permission="permissionList"
:before-open="beforeOpen"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad">
<template \#menu-left>
<el-button type="danger"
icon="el-icon-delete"
plain
v-if="permission.${modelCode!}_delete"
@click="handleDelete">删 除
</el-button>
<el-button type="warning"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
</avue-crud>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {exportBlob} from "@/api/common";
import {getToken} from '@/utils/auth';
import {downloadXls} from "@/utils/util";
import {dateNow} from "@/utils/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
form: {},
query: {},
search: {},
loading: true,
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
selectionList: [],
option: option,
data: []
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.${modelCode!}_add, false),
viewBtn: this.validData(this.permission.${modelCode!}_view, false),
delBtn: this.validData(this.permission.${modelCode!}_delete, false),
editBtn: this.validData(this.permission.${modelCode!}_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
rowSave(row, done, loading) {
add(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
window.console.log(error);
});
},
rowUpdate(row, index, done, loading) {
update(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
console.log(error);
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage){
this.page.currentPage = currentPage;
},
sizeChange(pageSize){
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
}
}
};
</script>
<style>
</style>
@@ -0,0 +1 @@
export default ${modelFormOption!}
@@ -0,0 +1,67 @@
export default {
height:'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
viewBtn: true,
selection: true,
dialogClickModal: false,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"editor")){
component: 'avue-ueditor',
options: {
action: '/blade-resource/oss/endpoint/put-file',
props: {
res: "data",
url: "link",
}
},
hide: true,
minRows: 6,
#}else{
type: "${x.componentType!}",
#}
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
#}
#if(isNotEmpty(x.dictCode)){
dicUrl: "/blade-system/dict/dictionary?code=${x.dictCode!}",
dataType: "number",
props: {
label: "dictValue",
value: "dictKey"
},
#}
#if(x.isForm==0){
addDisplay: false,
editDisplay: false,
viewDisplay: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
#if(x.isRequired==1){
rules: [{
required: true,
message: "请输入${x.jdbcComment!}",
trigger: "blur"
}],
#}
},
#}
]
}
@@ -0,0 +1,50 @@
import request from '@/axios';
export const getList = (current, size, params) => {
return request({
url: '/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const remove = (ids) => {
return request({
url: '/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,442 @@
<template>
<basic-container>
<avue-crud :option="option"
v-model:search="search"
v-model:page="page"
v-model="form"
:table-loading="loading"
:data="data"
:permission="permissionList"
:before-open="beforeOpen"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad">
<template \#menu-left>
<el-button type="danger"
icon="el-icon-delete"
plain
v-if="permission.${model.modelCode!}_delete"
@click="handleDelete">删 除
</el-button>
<el-button type="warning"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
<template \#menu="row">
<el-button type="text"
icon="el-icon-setting"
@click.stop="handleDataSub(row)">配 置
</el-button>
</template>
</avue-crud>
<el-drawer :title="`[\${${model.modelCode!}Name}] 配置`" v-model="subVisible" :direction="direction" append-to-body
:before-close="handleSubClose" size="1000px">
<basic-container>
<avue-crud :option="optionSub"
:data="dataSub"
v-model:page="pageSub"
v-model="formSub"
:table-loading="loadingSub"
ref="crudSub"
@row-del="rowDelSub"
@row-update="rowUpdateSub"
@row-save="rowSaveSub"
:before-open="beforeOpenSub"
@search-change="searchChangeSub"
@search-reset="searchResetSub"
@selection-change="selectionChangeSub"
@current-change="currentChangeSub"
@size-change="sizeChangeSub"
@on-load="onLoadSub">
<template \#menu-left>
<el-button type="danger"
icon="el-icon-delete"
plain
@click="handleDeleteSub">删 除
</el-button>
</template>
</avue-crud>
</basic-container>
</el-drawer>
</basic-container>
</template>
<script>
import {getList, getDetail, add, update, remove} from "@/api/${serviceCode!}/${model.modelCode!}";
import {getList as getListSub, getDetail as getDetailSub, add as addSub, update as updateSub, remove as removeSub} from "@/api/${serviceCode!}/${subModel.modelCode!}";
import option from "@/option/${serviceCode!}/${model.modelCode!}";
import optionSub from "@/option/${serviceCode!}/${subModel.modelCode!}";
import {mapGetters} from "vuex";
import {exportBlob} from "@/api/common";
import {getToken} from '@/utils/auth';
import {downloadXls} from "@/utils/util";
import {dateNow} from "@/utils/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
form: {},
query: {},
search: {},
loading: true,
data: [],
selectionList: [],
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
option: option,
subVisible: false,
direction: 'rtl',
${subFkIdHump!}: 0,
${model.modelCode!}Name: "${model.modelName!}",
formSub: {},
querySub: {},
loadingSub: true,
dataSub: [],
selectionListSub: [],
pageSub: {
pageSize: 10,
currentPage: 1,
total: 0
},
optionSub: optionSub
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.${model.modelCode!}_add, false),
viewBtn: this.validData(this.permission.${model.modelCode!}_view, false),
delBtn: this.validData(this.permission.${model.modelCode!}_delete, false),
editBtn: this.validData(this.permission.${model.modelCode!}_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
},
subIds() {
let ids = [];
this.selectionListSub.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
// 主表模块
rowSave(row, done, loading) {
add(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
window.console.log(error);
loading();
});
},
rowUpdate(row, index, done, loading) {
update(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
window.console.log(error);
loading();
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage){
this.page.currentPage = currentPage;
},
sizeChange(pageSize){
this.page.pageSize = pageSize;
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.page.total = data.total;
this.data = data.records;
this.loading = false;
this.selectionClear();
});
},
// 子表模块
handleDataSub(row) {
this.subVisible = true;
this.${subFkIdHump!} = row.id;
this.onLoadSub(this.pageSub)
},
handleSubClose(hide) {
hide();
},
rowSaveSub(row, loading, done) {
row = {
...row,
${subFkIdHump!}: this.${subFkIdHump!},
};
addSub(row).then(() => {
loading();
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
}, error => {
done();
window.console.log(error);
});
},
rowUpdateSub(row, index, loading, done) {
row = {
...row,
${subFkIdHump!}: this.${subFkIdHump!},
};
updateSub(row).then(() => {
loading();
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
}, error => {
done();
window.console.log(error);
});
},
rowDelSub(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return removeSub(row.id);
})
.then(() => {
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDeleteSub() {
if (this.selectionListSub.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return removeSub(this.subIds);
})
.then(() => {
this.onLoadSub(this.pageSub);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crudSub.toggleSelection();
});
},
beforeOpenSub(done, type) {
if (["edit", "view"].includes(type)) {
getDetailSub(this.formSub.id).then(res => {
this.formSub = res.data.data;
});
}
done();
},
searchResetSub() {
this.querySub = {};
this.onLoadSub(this.pageSub);
},
searchChangeSub(params) {
this.querySub = params;
this.onLoadSub(this.pageSub, params);
},
selectionChangeSub(list) {
this.selectionListSub = list;
},
currentChangeSub(currentPage) {
this.pageSub.currentPage = currentPage;
},
sizeChangeSub(pageSize) {
this.pageSub.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoadSub(page, params = {}) {
this.loadingSub = true;
let values = {
${subFkIdHump!}: this.${subFkIdHump!},
}
const {
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.querySub;
values = {
...values,
#for(x in subPrototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getListSub(page.currentPage, page.pageSize, values).then(res => {
const data = res.data.data;
this.pageSub.total = data.total;
this.dataSub = data.records;
this.selectionListSub = [];
this.loadingSub = false;
});
},
}
};
</script>
<style>
</style>
@@ -0,0 +1,67 @@
export default {
height:'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
viewBtn: true,
selection: true,
menuWidth: 300,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(strutil.contain(x.componentType,"editor")){
component: 'avue-ueditor',
options: {
action: '/blade-resource/oss/endpoint/put-file',
props: {
res: "data",
url: "link",
}
},
hide: true,
minRows: 6,
#}else{
type: "${x.componentType!}",
#}
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
#}
#if(isNotEmpty(x.dictCode)){
dicUrl: "/blade-system/dict/dictionary?code=${x.dictCode!}",
dataType: "number",
props: {
label: "dictValue",
value: "dictKey"
},
#}
#if(x.isForm==0){
addDisplay: false,
editDisplay: false,
viewDisplay: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
#if(x.isRequired==1&&isEmpty(x.validateRule)){
rules: [{
required: true,
message: "请输入${x.jdbcComment!}",
trigger: "blur"
}],
#}
},
#}
]
}
@@ -0,0 +1,60 @@
import request from '@/axios';
export const getList = (current, size, params) => {
return request({
url: '/${serviceName!}/${modelCode!}/list',
method: 'get',
params: {
...params,
current,
size,
}
})
}
export const getDetail = (id) => {
return request({
url: '/${serviceName!}/${modelCode!}/detail',
method: 'get',
params: {
id
}
})
}
export const getTree = (tenantId) => {
return request({
url: '/${serviceName!}/${modelCode!}/tree',
method: 'get',
params: {
tenantId,
}
})
}
export const remove = (ids) => {
return request({
url: '/${serviceName!}/${modelCode!}/remove',
method: 'post',
params: {
ids,
}
})
}
export const add = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
export const update = (row) => {
return request({
url: '/${serviceName!}/${modelCode!}/submit',
method: 'post',
data: row
})
}
@@ -0,0 +1,246 @@
<template>
<basic-container>
<avue-crud :option="option"
v-model:search="search"
v-model:page="page"
v-model="form"
:table-loading="loading"
:data="data"
:permission="permissionList"
:before-open="beforeOpen"
ref="crud"
@row-update="rowUpdate"
@row-save="rowSave"
@row-del="rowDel"
@search-change="searchChange"
@search-reset="searchReset"
@selection-change="selectionChange"
@current-change="currentChange"
@size-change="sizeChange"
@refresh-change="refreshChange"
@on-load="onLoad">
<template \#menu-left>
<el-button type="danger"
icon="el-icon-delete"
plain
v-if="permission.${modelCode!}_delete"
@click="handleDelete">删 除
</el-button>
<el-button type="warning"
plain
icon="el-icon-download"
@click="handleExport">导 出
</el-button>
</template>
</avue-crud>
</basic-container>
</template>
<script>
import {getList, getDetail, getTree, add, update, remove} from "@/api/${serviceCode!}/${modelCode!}";
import option from "@/option/${serviceCode!}/${modelCode!}";
import {mapGetters} from "vuex";
import {exportBlob} from "@/api/common";
import {getToken} from '@/utils/auth';
import {downloadXls} from "@/utils/util";
import {dateNow} from "@/utils/date";
import NProgress from 'nprogress';
import 'nprogress/nprogress.css';
export default {
data() {
return {
form: {},
query: {},
search: {},
loading: true,
page: {
pageSize: 10,
currentPage: 1,
total: 0
},
selectionList: [],
option: option,
data: []
};
},
computed: {
...mapGetters(["permission"]),
permissionList() {
return {
addBtn: this.validData(this.permission.${modelCode!}_add, false),
viewBtn: this.validData(this.permission.${modelCode!}_view, false),
delBtn: this.validData(this.permission.${modelCode!}_delete, false),
editBtn: this.validData(this.permission.${modelCode!}_edit, false)
};
},
ids() {
let ids = [];
this.selectionList.forEach(ele => {
ids.push(ele.id);
});
return ids.join(",");
}
},
methods: {
rowSave(row, done, loading) {
add(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
window.console.log(error);
});
},
rowUpdate(row, index, done, loading) {
update(row).then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
done();
}, error => {
loading();
console.log(error);
});
},
rowDel(row) {
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(row.id);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
});
},
handleDelete() {
if (this.selectionList.length === 0) {
this.$message.warning("请选择至少一条数据");
return;
}
this.$confirm("确定将选择数据删除?", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
})
.then(() => {
return remove(this.ids);
})
.then(() => {
this.onLoad(this.page);
this.$message({
type: "success",
message: "操作成功!"
});
this.$refs.crud.toggleSelection();
});
},
handleExport() {
let downloadUrl = `/${serviceName!}/${modelCode!}/export-${modelCode!}?\${this.website.tokenHeader}=\${getToken()}`;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
this.$confirm("是否导出数据?", "提示", {
confirmButtonText: "确定",
cancelButtonText: "取消",
type: "warning"
}).then(() => {
NProgress.start();
exportBlob(downloadUrl, values).then(res => {
downloadXls(res.data, `${codeName!}\${dateNow()}.xlsx`);
NProgress.done();
})
});
},
beforeOpen(done, type) {
if (["edit", "view"].includes(type)) {
getDetail(this.form.id).then(res => {
this.form = res.data.data;
});
}
done();
},
searchReset() {
this.query = {};
this.onLoad(this.page);
},
searchChange(params, done) {
this.query = params;
this.page.currentPage = 1;
this.onLoad(this.page, params);
done();
},
selectionChange(list) {
this.selectionList = list;
},
selectionClear() {
this.selectionList = [];
this.$refs.crud.toggleSelection();
},
currentChange(currentPage){
this.page.currentPage = currentPage;
},
sizeChange(pageSize){
this.page.pageSize = pageSize;
},
refreshChange() {
this.onLoad(this.page, this.query);
},
onLoad(page, params = {}) {
this.loading = true;
const {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!},
#}
#}
} = this.query;
let values = {
#for(x in prototypes) {
#if(x.isQuery==1){
${x.propertyName!}_${x.queryType!}: ${x.propertyName!},
#}
#}
};
getList(page.currentPage, page.pageSize, values).then(res => {
this.data = res.data.data;
this.loading = false;
getTree().then(res => {
const column = this.findObject(this.option.column, "${treePidHump!}");
column.dicData = res.data.data;
});
});
}
}
};
</script>
<style>
</style>
@@ -0,0 +1,74 @@
export default {
height:'auto',
calcHeight: 30,
tip: false,
searchShow: true,
searchMenuSpan: 6,
border: true,
index: true,
viewBtn: true,
selection: true,
dialogClickModal: false,
column: [
#for(x in prototypes) {
{
label: "${x.jdbcComment!}",
prop: "${x.propertyName!}",
#if(x.propertyName==treePidHump){
type: "tree",
dicData: [],
props: {
label: "title",
},
value: 0,
#}else if(strutil.contain(x.componentType,"editor")){
component: 'avue-ueditor',
options: {
action: '/blade-resource/oss/endpoint/put-file',
props: {
res: "data",
url: "link",
}
},
hide: true,
minRows: 6,
#}else{
type: "${x.componentType!}",
#}
#if(strutil.contain(x.componentType,"date")||strutil.contain(x.componentType,"time")){
format: "YYYY-MM-DD HH:mm:ss",
valueFormat: "YYYY-MM-DD HH:mm:ss",
#}
#if(isNotEmpty(x.dictCode)&&x.propertyName!=treePidHump){
dicUrl: "/blade-system/dict/dictionary?code=${x.dictCode!}",
dataType: "number",
props: {
label: "dictValue",
value: "dictKey"
},
#}
#if(x.isForm==0){
addDisplay: false,
editDisplay: false,
viewDisplay: false,
#}
#if(x.isRow==1){
span: 24,
#}
#if(x.isList==0){
hide: true,
#}
#if(x.isQuery==1){
search: true,
#}
#if(x.isRequired==1){
rules: [{
required: true,
message: "请输入${x.jdbcComment!}",
trigger: "blur"
}],
#}
},
#}
]
}
@@ -0,0 +1,10 @@
INSERT INTO blade_menu(id, parent_id, code, name, alias, path, source, sort, category, action, is_open, remark, is_deleted)
VALUES ('${menuId}', '${parentMenuId}', '${modelCode!}', '${codeName!}', 'menu', '/${serviceCode!}/${modelCode!}', NULL, 1, 1, 0, 1, NULL, 0);
INSERT INTO blade_menu(id, parent_id, code, name, alias, path, source, sort, category, action, is_open, remark, is_deleted)
VALUES ('${addMenuId}', '${menuId}', '${modelCode!}_add', '新增', 'add', '/${serviceCode!}/${modelCode!}/add', 'plus', 1, 2, 1, 1, NULL, 0);
INSERT INTO blade_menu(id, parent_id, code, name, alias, path, source, sort, category, action, is_open, remark, is_deleted)
VALUES ('${editMenuId}', '${menuId}', '${modelCode!}_edit', '修改', 'edit', '/${serviceCode!}/${modelCode!}/edit', 'form', 2, 2, 2, 1, NULL, 0);
INSERT INTO blade_menu(id, parent_id, code, name, alias, path, source, sort, category, action, is_open, remark, is_deleted)
VALUES ('${removeMenuId}', '${menuId}', '${modelCode!}_delete', '删除', 'delete', '/api/${serviceName!}/${modelCode!}/remove', 'delete', 3, 2, 3, 1, NULL, 0);
INSERT INTO blade_menu(id, parent_id, code, name, alias, path, source, sort, category, action, is_open, remark, is_deleted)
VALUES ('${viewMenuId}', '${menuId}', '${modelCode!}_view', '查看', 'view', '/${serviceCode!}/${modelCode!}/view', 'file-text', 4, 2, 2, 1, NULL, 0);