This commit is contained in:
2025-11-28 16:23:32 +08:00
commit a9e0e16c29
826 changed files with 89805 additions and 0 deletions

View File

@@ -0,0 +1,40 @@
<?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>
<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>
<version>3.10.0.Antlr4.5-RELEASE</version>
</dependency>
</dependencies>
</project>

View File

@@ -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();
}
}

View File

@@ -0,0 +1,83 @@
/**
* 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 {
/**
* 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";
}

View File

@@ -0,0 +1,381 @@
/**
* 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.generator.FastAutoGenerator;
import com.baomidou.mybatisplus.generator.config.TemplateType;
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.*;
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;
/**
* 作者信息
*/
private String author;
/**
* 子表模型主键
*/
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;
/**
* 基础业务字段
*/
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 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);
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("templateType", templateType);
customMap.put("author", author);
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));
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"))).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");
}
} 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 = 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(StringUtil.isBlank(author) ? props.getProperty("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.mp.base.BaseEntity").formatFileName("%sEntity").addSuperEntityColumns(superEntityColumns).enableFileOverride()
.serviceBuilder().superServiceClass("org.springblade.core.mp.base.BaseService").superServiceImplClass("org.springblade.core.mp.base.BaseServiceImpl").formatServiceFileName("I%sService").formatServiceImplFileName("%sServiceImpl").enableFileOverride()
.mapperBuilder().mapperAnnotation(Mapper.class).enableBaseResultMap().enableBaseColumnList().formatMapperFileName("%sMapper").formatXmlFileName("%sMapper").enableFileOverride()
.controllerBuilder().superClass("org.springblade.core.boot.ctrl.BladeController").formatFileName("%sController").enableRestStyle().enableHyphenStyle().enableFileOverride()
)
.templateConfig(builder -> builder.disable(TemplateType.ENTITY)
.entity("/templates/api/entity.java")
.service("/templates/api/service.java")
.serviceImpl("/templates/api/serviceImpl.java")
.mapper("/templates/api/mapper.java")
.xml("/templates/api/mapper.xml")
.controller("/templates/api/controller.java"))
.injectionConfig(builder -> builder.beforeOutputFile(
(tableInfo, objectMap) -> System.out.println("tableInfo: " + tableInfo.getEntityName() + " objectMap: " + objectMap.size())
).customMap(customMap).customFile(customFile)
);
}
/**
* 获取配置文件
*
* @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";
}
}

View File

@@ -0,0 +1,166 @@
/**
* 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.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;
@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 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")) {
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);
});
}
}

View File

@@ -0,0 +1,10 @@
#默认配置
ENGINE = org.beetl.core.engine.FastRuntimeEngine
#开始结束占位符
DELIMITER_PLACEHOLDER_START = ${
DELIMITER_PLACEHOLDER_END = }
#开始结束标签
DELIMITER_STATEMENT_START = #
DELIMITER_STATEMENT_END = null

View File

@@ -0,0 +1,253 @@
/**
* 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.PreAuth;
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!}.pojo.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 org.springblade.core.tool.constant.RoleConstant;
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(name = "主键集合", 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(name = "主键集合", 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);
}
#}
/**
* 导出数据
*/
@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
@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);
}
}

View File

@@ -0,0 +1,92 @@
/**
* 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 com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.media.Schema;
#for(x in propertyImport){
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;
#}
/**
* ${codeName!} 实体类
*
* @author ${author!}
* @since ${date!}
*/
@Data
@TableName("${model.modelTable!}")
@Schema(description = "${modelClass!}对象")
#if(hasSuperEntity){
@EqualsAndHashCode(callSuper = true)
public class ${modelClass!}Entity extends TenantEntity {
#}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.propertyName!="createUser"&&x.propertyName!="createDept"&&x.propertyName!="createTime"&&x.propertyName!="updateUser"&&x.propertyName!="updateTime"&&x.propertyName!="status"){
/**
* ${x.jdbcComment!}
*/
@Schema(description = "${x.jdbcComment!}")
private ${x.propertyType!} ${x.propertyName!};
#}
#}
#}
}

View File

@@ -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;
}

View File

@@ -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 ${strutil.replace(package.Entity,"pojo.entity","excel")};
import lombok.Data;
#for(x in propertyImport){
import ${x!};
#}
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentRowHeight;
import com.alibaba.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!="id"&&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!};
#}
#}
}

View File

@@ -0,0 +1,99 @@
/**
* 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;
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;
}
#}

View File

@@ -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,"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 = "/client";
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);
}

View File

@@ -0,0 +1,61 @@
/**
* 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","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 ${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 = service.page(Condition.getPage(query));
return BladePage.of(page);
}
}

View File

@@ -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!}.pojo.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> select${modelClass!}Page(IPage page, ${modelClass!}VO ${modelCode!});
#if(templateType=="tree"){
/**
* 获取树形节点
*
* @param tenantId
* @return
*/
List<${modelClass!}VO> tree(String tenantId);
#}
/**
* 获取导出数据
*
* @param queryWrapper
* @return
*/
List<${modelClass!}Excel> export${modelClass!}(@Param("ew") Wrapper<${modelClass!}Entity> queryWrapper);
}

View File

@@ -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!}.pojo.excel.${modelClass!}Excel">
SELECT * FROM ${model.modelTable!} \${ew.customSqlSegment}
</select>
</mapper>

View File

@@ -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!}.pojo.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> select${modelClass!}Page(IPage<${modelClass!}VO> page, ${modelClass!}VO ${modelCode!});
#if(templateType=="tree"){
/**
* 树形结构
*
* @param tenantId
* @return
*/
List<${modelClass!}VO> tree(String tenantId);
#}
/**
* 导出数据
*
* @param queryWrapper
* @return
*/
List<${modelClass!}Excel> export${modelClass!}(Wrapper<${modelClass!}Entity> queryWrapper);
}

View File

@@ -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!}.pojo.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;
}
}

View File

@@ -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);
}
#}
}

View File

@@ -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

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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,
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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,
#}
},
#}
]
}

View File

@@ -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>

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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,
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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,
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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,
#}
},
#}
]
}

View File

@@ -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>

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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,
#}
},
#}
]
}

View File

@@ -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>

View File

@@ -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!}",
},
#}
#}
];

View File

@@ -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 });
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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!}",
},
#}
#}
];

View File

@@ -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 });
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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!}",
},
#}
#}
];

View File

@@ -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 });
}

View File

@@ -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>

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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"
}],
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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"
}],
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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"
}],
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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"
}],
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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"
}],
#}
},
#}
]
}

View File

@@ -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
})
}

View File

@@ -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>

View File

@@ -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"
}],
#}
},
#}
]
}

View File

@@ -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}', 1123598815738675201, '${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);

View File

@@ -0,0 +1,37 @@
#set($upperEntityPath=$table.entityPath.toUpperCase())
export const $!{upperEntityPath}_NAMESPACE = '$!{table.entityPath}';
export function $!{upperEntityPath}_LIST(payload) {
return {
type: `${$!{upperEntityPath}_NAMESPACE}/fetchList`,
payload,
};
}
export function $!{upperEntityPath}_DETAIL(id) {
return {
type: `${$!{upperEntityPath}_NAMESPACE}/fetchDetail`,
payload: { id },
};
}
export function $!{upperEntityPath}_CLEAR_DETAIL() {
return {
type: `${$!{upperEntityPath}_NAMESPACE}/clearDetail`,
payload: {},
};
}
export function $!{upperEntityPath}_SUBMIT(payload) {
return {
type: `${$!{upperEntityPath}_NAMESPACE}/submit`,
payload,
};
}
export function $!{upperEntityPath}_REMOVE(payload) {
return {
type: `${$!{upperEntityPath}_NAMESPACE}/remove`,
payload,
};
}

View File

@@ -0,0 +1,75 @@
#set($upperEntityPath=$table.entityPath.toUpperCase())
import React, { PureComponent } from 'react';
import { Form, Input, Card, Button } from 'antd';
import { connect } from 'dva';
import Panel from '../../../components/Panel';
import styles from '../../../layouts/Sword.less';
import { $!{upperEntityPath}_SUBMIT } from '../../../actions/$!{table.entityPath}';
const FormItem = Form.Item;
@connect(({ loading }) => ({
submitting: loading.effects['$!{table.entityPath}/submit'],
}))
@Form.create()
class $!{entity}Add extends PureComponent {
handleSubmit = e => {
e.preventDefault();
const { dispatch, form } = this.props;
form.validateFieldsAndScroll((err, values) => {
if (!err) {
dispatch($!{upperEntityPath}_SUBMIT(values));
}
});
};
render() {
const {
form: { getFieldDecorator },
submitting,
} = this.props;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 7 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
md: { span: 10 },
},
};
const action = (
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
提交
</Button>
);
return (
<Panel title="新增" back="/$!{servicePackage}/$!{table.entityPath}" action={action}>
<Form hideRequiredMark style={{ marginTop: 8 }}>
<Card className={styles.card} bordered={false}>
#foreach($field in $!{table.fields})
#if($!{field.name}!=$!{tenantColumn})
<FormItem {...formItemLayout} label="$!{field.comment}">
{getFieldDecorator('$!{field.propertyName}', {
rules: [
{
required: true,
message: '请输入$!{field.comment}',
},
],
})(<Input placeholder="请输入$!{field.comment}" />)}
</FormItem>
#end
#end
</Card>
</Form>
</Panel>
);
}
}
export default $!{entity}Add;

View File

@@ -0,0 +1,99 @@
#set($upperEntityPath=$table.entityPath.toUpperCase())
import React, { PureComponent } from 'react';
import { Form, Input, Card, Button } from 'antd';
import { connect } from 'dva';
import Panel from '../../../components/Panel';
import styles from '../../../layouts/Sword.less';
import { $!{upperEntityPath}_DETAIL, $!{upperEntityPath}_SUBMIT } from '../../../actions/$!{table.entityPath}';
const FormItem = Form.Item;
@connect(({ $!{table.entityPath}, loading }) => ({
$!{table.entityPath},
submitting: loading.effects['$!{table.entityPath}/submit'],
}))
@Form.create()
class $!{entity}Edit extends PureComponent {
componentWillMount() {
const {
dispatch,
match: {
params: { id },
},
} = this.props;
dispatch($!{upperEntityPath}_DETAIL(id));
}
handleSubmit = e => {
e.preventDefault();
const {
dispatch,
match: {
params: { id },
},
form,
} = this.props;
form.validateFieldsAndScroll((err, values) => {
if (!err) {
const params = {
id,
...values,
};
console.log(params);
dispatch($!{upperEntityPath}_SUBMIT(params));
}
});
};
render() {
const {
form: { getFieldDecorator },
$!{table.entityPath}: { detail },
submitting,
} = this.props;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 7 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
md: { span: 10 },
},
};
const action = (
<Button type="primary" onClick={this.handleSubmit} loading={submitting}>
提交
</Button>
);
return (
<Panel title="修改" back="/$!{servicePackage}/$!{table.entityPath}" action={action}>
<Form hideRequiredMark style={{ marginTop: 8 }}>
<Card className={styles.card} bordered={false}>
#foreach($field in $!{table.fields})
#if($!{field.name}!=$!{tenantColumn})
<FormItem {...formItemLayout} label="$!{field.comment}">
{getFieldDecorator('$!{field.propertyName}', {
rules: [
{
required: true,
message: '请输入$!{field.comment}',
},
],
initialValue: detail.$!{field.propertyName},
})(<Input placeholder="请输入$!{field.comment}" />)}
</FormItem>
#end
#end
</Card>
</Form>
</Panel>
);
}
}
export default $!{entity}Edit;

View File

@@ -0,0 +1,84 @@
#set($upperEntityPath=$table.entityPath.toUpperCase())
import React, { PureComponent } from 'react';
import { connect } from 'dva';
import { Button, Col, Form, Input, Row } from 'antd';
import Panel from '../../../components/Panel';
import { $!{upperEntityPath}_LIST } from '../../../actions/$!{table.entityPath}';
import Grid from '../../../components/Sword/Grid';
const FormItem = Form.Item;
@connect(({ $!{table.entityPath}, loading }) => ({
$!{table.entityPath},
loading: loading.models.$!{table.entityPath},
}))
@Form.create()
class $!{entity} extends PureComponent {
// ============ 查询 ===============
handleSearch = params => {
const { dispatch } = this.props;
dispatch($!{upperEntityPath}_LIST(params));
};
// ============ 查询表单 ===============
renderSearchForm = onReset => {
const { form } = this.props;
const { getFieldDecorator } = form;
return (
<Row gutter={{ md: 8, lg: 24, xl: 48 }}>
<Col md={6} sm={24}>
<FormItem label="查询名称">
{getFieldDecorator('name')(<Input placeholder="查询名称" />)}
</FormItem>
</Col>
<Col>
<div style={{ float: 'right' }}>
<Button type="primary" htmlType="submit">
查询
</Button>
<Button style={{ marginLeft: 8 }} onClick={onReset}>
重置
</Button>
</div>
</Col>
</Row>
);
};
render() {
const code = '$!{table.entityPath}';
const {
form,
loading,
$!{table.entityPath}: { data },
} = this.props;
const columns = [
#foreach($field in $!{table.fields})
#if($!{field.name}!=$!{tenantColumn})
{
title: '$!{field.comment}',
dataIndex: '$!{field.propertyName}',
},
#end
#end
];
return (
<Panel>
<Grid
code={code}
form={form}
onSearch={this.handleSearch}
renderSearchForm={this.renderSearchForm}
loading={loading}
data={data}
columns={columns}
/>
</Panel>
);
}
}
export default $!{entity};

View File

@@ -0,0 +1,88 @@
#set($upperEntityPath=$table.entityPath.toUpperCase())
import { message } from 'antd';
import router from 'umi/router';
import { $!{upperEntityPath}_NAMESPACE } from '../actions/$!{table.entityPath}';
import { list, submit, detail, remove } from '../services/$!{table.entityPath}';
export default {
namespace: $!{upperEntityPath}_NAMESPACE,
state: {
data: {
list: [],
pagination: false,
},
detail: {},
},
effects: {
*fetchList({ payload }, { call, put }) {
const response = yield call(list, payload);
if (response.success) {
yield put({
type: 'saveList',
payload: {
list: response.data.records,
pagination: {
total: response.data.total,
current: response.data.current,
pageSize: response.data.size,
},
},
});
}
},
*fetchDetail({ payload }, { call, put }) {
const response = yield call(detail, payload);
if (response.success) {
yield put({
type: 'saveDetail',
payload: {
detail: response.data,
},
});
}
},
*clearDetail({ payload }, { put }) {
yield put({
type: 'removeDetail',
payload: { payload },
});
},
*submit({ payload }, { call }) {
const response = yield call(submit, payload);
if (response.success) {
message.success('提交成功');
router.push('/$!{servicePackage}/$!{table.entityPath}');
}
},
*remove({ payload }, { call }) {
const {
data: { keys },
success,
} = payload;
const response = yield call(remove, { ids: keys });
if (response.success) {
success();
}
},
},
reducers: {
saveList(state, action) {
return {
...state,
data: action.payload,
};
},
saveDetail(state, action) {
return {
...state,
detail: action.payload.detail,
};
},
removeDetail(state) {
return {
...state,
detail: {},
};
},
},
};

View File

@@ -0,0 +1,26 @@
#set($params="$" + "{stringify" + "(params)" + "}")
import { stringify } from 'qs';
import func from '../utils/Func';
import request from '../utils/request';
export async function list(params) {
return request(`/api/$!{serviceName}/$!{entityKey}/list?$!{params}`);
}
export async function submit(params) {
return request('/api/$!{serviceName}/$!{entityKey}/submit', {
method: 'POST',
body: params,
});
}
export async function detail(params) {
return request(`/api/$!{serviceName}/$!{entityKey}/detail?$!{params}`);
}
export async function remove(params) {
return request('/api/$!{serviceName}/$!{entityKey}/remove', {
method: 'POST',
body: func.toFormData(params),
});
}

View File

@@ -0,0 +1,77 @@
#set($upperEntityPath=$table.entityPath.toUpperCase())
#set($editId="$" + "{" + "id" + "}")
import React, { PureComponent } from 'react';
import router from 'umi/router';
import { Form, Card, Button } from 'antd';
import { connect } from 'dva';
import Panel from '../../../components/Panel';
import styles from '../../../layouts/Sword.less';
import { $!{upperEntityPath}_DETAIL } from '../../../actions/$!{table.entityPath}';
const FormItem = Form.Item;
@connect(({ $!{table.entityPath} }) => ({
$!{table.entityPath},
}))
@Form.create()
class $!{entity}View extends PureComponent {
componentWillMount() {
const {
dispatch,
match: {
params: { id },
},
} = this.props;
dispatch($!{upperEntityPath}_DETAIL(id));
}
handleEdit = () => {
const {
match: {
params: { id },
},
} = this.props;
router.push(`/$!{servicePackage}/$!{table.entityPath}/edit/$!{editId}`);
};
render() {
const {
$!{table.entityPath}: { detail },
} = this.props;
const formItemLayout = {
labelCol: {
xs: { span: 24 },
sm: { span: 7 },
},
wrapperCol: {
xs: { span: 24 },
sm: { span: 12 },
md: { span: 10 },
},
};
const action = (
<Button type="primary" onClick={this.handleEdit}>
修改
</Button>
);
return (
<Panel title="查看" back="/$!{servicePackage}/$!{table.entityPath}" action={action}>
<Form hideRequiredMark style={{ marginTop: 8 }}>
<Card className={styles.card} bordered={false}>
#foreach($field in $!{table.fields})
#if($!{field.name}!=$!{tenantColumn})
<FormItem {...formItemLayout} label="$!{field.comment}">
<span>{detail.$!{field.propertyName}}</span>
</FormItem>
#end
#end
</Card>
</Form>
</Panel>
);
}
}
export default $!{entity}View;