init
This commit is contained in:
		| @ -0,0 +1,73 @@ | ||||
| package org.dromara.generator.config; | ||||
|  | ||||
| import org.springframework.beans.factory.annotation.Value; | ||||
| import org.springframework.boot.context.properties.ConfigurationProperties; | ||||
| import org.springframework.context.annotation.PropertySource; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| /** | ||||
|  * 读取代码生成相关配置 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| @Component | ||||
| @ConfigurationProperties(prefix = "gen") | ||||
| @PropertySource(value = {"classpath:generator.yml"}, encoding = "UTF-8") | ||||
| public class GenConfig { | ||||
|  | ||||
|     /** | ||||
|      * 作者 | ||||
|      */ | ||||
|     public static String author; | ||||
|  | ||||
|     /** | ||||
|      * 生成包路径 | ||||
|      */ | ||||
|     public static String packageName; | ||||
|  | ||||
|     /** | ||||
|      * 自动去除表前缀,默认是false | ||||
|      */ | ||||
|     public static boolean autoRemovePre; | ||||
|  | ||||
|     /** | ||||
|      * 表前缀(类名不会包含表前缀) | ||||
|      */ | ||||
|     public static String tablePrefix; | ||||
|  | ||||
|     public static String getAuthor() { | ||||
|         return author; | ||||
|     } | ||||
|  | ||||
|     @Value("${author}") | ||||
|     public void setAuthor(String author) { | ||||
|         GenConfig.author = author; | ||||
|     } | ||||
|  | ||||
|     public static String getPackageName() { | ||||
|         return packageName; | ||||
|     } | ||||
|  | ||||
|     @Value("${packageName}") | ||||
|     public void setPackageName(String packageName) { | ||||
|         GenConfig.packageName = packageName; | ||||
|     } | ||||
|  | ||||
|     public static boolean getAutoRemovePre() { | ||||
|         return autoRemovePre; | ||||
|     } | ||||
|  | ||||
|     @Value("${autoRemovePre}") | ||||
|     public void setAutoRemovePre(boolean autoRemovePre) { | ||||
|         GenConfig.autoRemovePre = autoRemovePre; | ||||
|     } | ||||
|  | ||||
|     public static String getTablePrefix() { | ||||
|         return tablePrefix; | ||||
|     } | ||||
|  | ||||
|     @Value("${tablePrefix}") | ||||
|     public void setTablePrefix(String tablePrefix) { | ||||
|         GenConfig.tablePrefix = tablePrefix; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,105 @@ | ||||
| package org.dromara.generator.config; | ||||
|  | ||||
| import com.baomidou.dynamic.datasource.DynamicRoutingDataSource; | ||||
| import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.anyline.data.datasource.DataSourceMonitor; | ||||
| import org.anyline.data.runtime.DataRuntime; | ||||
| import org.anyline.util.ConfigTable; | ||||
| import org.springframework.jdbc.core.JdbcTemplate; | ||||
| import org.springframework.jdbc.datasource.DataSourceUtils; | ||||
| import org.springframework.stereotype.Component; | ||||
|  | ||||
| import javax.sql.DataSource; | ||||
| import java.sql.Connection; | ||||
| import java.sql.DatabaseMetaData; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * anyline 适配 动态数据源改造 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| @Slf4j | ||||
| @Component | ||||
| public class MyBatisDataSourceMonitor implements DataSourceMonitor { | ||||
|  | ||||
|     public MyBatisDataSourceMonitor() { | ||||
|         // 调整执行模式为自定义 | ||||
|         ConfigTable.KEEP_ADAPTER = 2; | ||||
|         // 禁用缓存 | ||||
|         ConfigTable.METADATA_CACHE_SCOPE = 0; | ||||
|     } | ||||
|  | ||||
|     private final Map<String, String> features = new HashMap<>(); | ||||
|  | ||||
|     /** | ||||
|      * 数据源特征 用来定准 adapter 包含数据库或JDBC协议关键字<br/> | ||||
|      * 一般会通过 产品名_url 合成 如果返回null 上层方法会通过driver_产品名_url合成 | ||||
|      * | ||||
|      * @param datasource 数据源 | ||||
|      * @return String 返回null由上层自动提取 | ||||
|      */ | ||||
|     @Override | ||||
|     public String feature(DataRuntime runtime, Object datasource) { | ||||
|         String feature = null; | ||||
|         if (datasource instanceof JdbcTemplate jdbc) { | ||||
|             DataSource ds = jdbc.getDataSource(); | ||||
|             if (ds instanceof DynamicRoutingDataSource) { | ||||
|                 String key = DynamicDataSourceContextHolder.peek(); | ||||
|                 feature = features.get(key); | ||||
|                 if (null == feature) { | ||||
|                     Connection con = null; | ||||
|                     try { | ||||
|                         con = DataSourceUtils.getConnection(ds); | ||||
|                         DatabaseMetaData meta = con.getMetaData(); | ||||
|                         String url = meta.getURL(); | ||||
|                         feature = meta.getDatabaseProductName().toLowerCase().replace(" ", "") + "_" + url; | ||||
|                         features.put(key, feature); | ||||
|                     } catch (Exception e) { | ||||
|                         log.error(e.getMessage(), e); | ||||
|                     } finally { | ||||
|                         if (null != con && !DataSourceUtils.isConnectionTransactional(con, ds)) { | ||||
|                             DataSourceUtils.releaseConnection(con, ds); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return feature; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 数据源唯一标识 如果不实现则默认feature | ||||
|      * @param datasource 数据源 | ||||
|      * @return String 返回null由上层自动提取 | ||||
|      */ | ||||
|     @Override | ||||
|     public String key(DataRuntime runtime, Object datasource) { | ||||
|         if(datasource instanceof JdbcTemplate jdbc){ | ||||
|             DataSource ds = jdbc.getDataSource(); | ||||
|             if(ds instanceof DynamicRoutingDataSource){ | ||||
|                 return DynamicDataSourceContextHolder.peek(); | ||||
|             } | ||||
|         } | ||||
|         return runtime.getKey(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * ConfigTable.KEEP_ADAPTER=2 : 根据当前接口判断是否保持同一个数据源绑定同一个adapter<br/> | ||||
|      * DynamicRoutingDataSource类型的返回false,因为同一个DynamicRoutingDataSource可能对应多类数据库, 如果项目中只有一种数据库 应该直接返回true | ||||
|      * | ||||
|      * @param datasource 数据源 | ||||
|      * @return boolean | ||||
|      */ | ||||
|     @Override | ||||
|     public boolean keepAdapter(DataRuntime runtime, Object datasource) { | ||||
|         if (datasource instanceof JdbcTemplate jdbc) { | ||||
|             DataSource ds = jdbc.getDataSource(); | ||||
|             return !(ds instanceof DynamicRoutingDataSource); | ||||
|         } | ||||
|         return true; | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,186 @@ | ||||
| package org.dromara.generator.constant; | ||||
|  | ||||
| /** | ||||
|  * 代码生成通用常量 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| public interface GenConstants { | ||||
|     /** | ||||
|      * 单表(增删改查) | ||||
|      */ | ||||
|     String TPL_CRUD = "crud"; | ||||
|  | ||||
|     /** | ||||
|      * 树表(增删改查) | ||||
|      */ | ||||
|     String TPL_TREE = "tree"; | ||||
|  | ||||
|     /** | ||||
|      * 树编码字段 | ||||
|      */ | ||||
|     String TREE_CODE = "treeCode"; | ||||
|  | ||||
|     /** | ||||
|      * 树父编码字段 | ||||
|      */ | ||||
|     String TREE_PARENT_CODE = "treeParentCode"; | ||||
|  | ||||
|     /** | ||||
|      * 树名称字段 | ||||
|      */ | ||||
|     String TREE_NAME = "treeName"; | ||||
|  | ||||
|     /** | ||||
|      * 上级菜单ID字段 | ||||
|      */ | ||||
|     String PARENT_MENU_ID = "parentMenuId"; | ||||
|  | ||||
|     /** | ||||
|      * 上级菜单名称字段 | ||||
|      */ | ||||
|     String PARENT_MENU_NAME = "parentMenuName"; | ||||
|  | ||||
|     /** | ||||
|      * 数据库字符串类型 | ||||
|      */ | ||||
|     String[] COLUMNTYPE_STR = {"char", "varchar", "enum", "set", "nchar", "nvarchar", "varchar2", "nvarchar2"}; | ||||
|  | ||||
|     /** | ||||
|      * 数据库文本类型 | ||||
|      */ | ||||
|     String[] COLUMNTYPE_TEXT = {"tinytext", "text", "mediumtext", "longtext", "binary", "varbinary", "blob", | ||||
|         "ntext", "image", "bytea"}; | ||||
|  | ||||
|     /** | ||||
|      * 数据库时间类型 | ||||
|      */ | ||||
|     String[] COLUMNTYPE_TIME = {"datetime", "time", "date", "timestamp", "year", "interval", | ||||
|         "smalldatetime", "datetime2", "datetimeoffset", "timestamptz"}; | ||||
|  | ||||
|     /** | ||||
|      * 数据库数字类型 | ||||
|      */ | ||||
|     String[] COLUMNTYPE_NUMBER = {"tinyint", "smallint", "mediumint", "int", "int2", "int4", "int8", "number", "integer", | ||||
|         "bit", "bigint", "float", "float4", "float8", "double", "decimal", "numeric", "real", "double precision", | ||||
|         "smallserial", "serial", "bigserial", "money", "smallmoney"}; | ||||
|  | ||||
|     /** | ||||
|      * BO对象 不需要添加字段 | ||||
|      */ | ||||
|     String[] COLUMNNAME_NOT_ADD = {"create_dept", "create_by", "create_time", "del_flag", "update_by", | ||||
|         "update_time", "version", "tenant_id"}; | ||||
|  | ||||
|     /** | ||||
|      * BO对象 不需要编辑字段 | ||||
|      */ | ||||
|     String[] COLUMNNAME_NOT_EDIT = {"create_dept", "create_by", "create_time", "del_flag", "update_by", | ||||
|         "update_time", "version", "tenant_id"}; | ||||
|  | ||||
|     /** | ||||
|      * VO对象 不需要返回字段 | ||||
|      */ | ||||
|     String[] COLUMNNAME_NOT_LIST = {"create_dept", "create_by", "create_time", "del_flag", "update_by", | ||||
|         "update_time", "version", "tenant_id"}; | ||||
|  | ||||
|     /** | ||||
|      * BO对象 不需要查询字段 | ||||
|      */ | ||||
|     String[] COLUMNNAME_NOT_QUERY = {"id", "create_dept", "create_by", "create_time", "del_flag", "update_by", | ||||
|         "update_time", "remark", "version", "tenant_id"}; | ||||
|  | ||||
|     /** | ||||
|      * Entity基类字段 | ||||
|      */ | ||||
|     String[] BASE_ENTITY = {"createDept", "createBy", "createTime", "updateBy", "updateTime", "tenantId"}; | ||||
|  | ||||
|     /** | ||||
|      * 文本框 | ||||
|      */ | ||||
|     String HTML_INPUT = "input"; | ||||
|  | ||||
|     /** | ||||
|      * 文本域 | ||||
|      */ | ||||
|     String HTML_TEXTAREA = "textarea"; | ||||
|  | ||||
|     /** | ||||
|      * 下拉框 | ||||
|      */ | ||||
|     String HTML_SELECT = "select"; | ||||
|  | ||||
|     /** | ||||
|      * 单选框 | ||||
|      */ | ||||
|     String HTML_RADIO = "radio"; | ||||
|  | ||||
|     /** | ||||
|      * 复选框 | ||||
|      */ | ||||
|     String HTML_CHECKBOX = "checkbox"; | ||||
|  | ||||
|     /** | ||||
|      * 日期控件 | ||||
|      */ | ||||
|     String HTML_DATETIME = "datetime"; | ||||
|  | ||||
|     /** | ||||
|      * 图片上传控件 | ||||
|      */ | ||||
|     String HTML_IMAGE_UPLOAD = "imageUpload"; | ||||
|  | ||||
|     /** | ||||
|      * 文件上传控件 | ||||
|      */ | ||||
|     String HTML_FILE_UPLOAD = "fileUpload"; | ||||
|  | ||||
|     /** | ||||
|      * 富文本控件 | ||||
|      */ | ||||
|     String HTML_EDITOR = "editor"; | ||||
|  | ||||
|     /** | ||||
|      * 字符串类型 | ||||
|      */ | ||||
|     String TYPE_STRING = "String"; | ||||
|  | ||||
|     /** | ||||
|      * 整型 | ||||
|      */ | ||||
|     String TYPE_INTEGER = "Integer"; | ||||
|  | ||||
|     /** | ||||
|      * 长整型 | ||||
|      */ | ||||
|     String TYPE_LONG = "Long"; | ||||
|  | ||||
|     /** | ||||
|      * 浮点型 | ||||
|      */ | ||||
|     String TYPE_DOUBLE = "Double"; | ||||
|  | ||||
|     /** | ||||
|      * 高精度计算类型 | ||||
|      */ | ||||
|     String TYPE_BIGDECIMAL = "BigDecimal"; | ||||
|  | ||||
|     /** | ||||
|      * 时间类型 | ||||
|      */ | ||||
|     String TYPE_DATE = "Date"; | ||||
|  | ||||
|     /** | ||||
|      * 模糊查询 | ||||
|      */ | ||||
|     String QUERY_LIKE = "LIKE"; | ||||
|  | ||||
|     /** | ||||
|      * 相等查询 | ||||
|      */ | ||||
|     String QUERY_EQ = "EQ"; | ||||
|  | ||||
|     /** | ||||
|      * 需要 | ||||
|      */ | ||||
|     String REQUIRE = "1"; | ||||
| } | ||||
| @ -0,0 +1,217 @@ | ||||
| package org.dromara.generator.controller; | ||||
|  | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.io.IoUtil; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.mybatis.helper.DataBaseHelper; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.generator.domain.GenTable; | ||||
| import org.dromara.generator.domain.GenTableColumn; | ||||
| import org.dromara.generator.service.IGenTableService; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
|  | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import java.io.IOException; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * 代码生成 操作处理 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/tool/gen") | ||||
| public class GenController extends BaseController { | ||||
|  | ||||
|     private final IGenTableService genTableService; | ||||
|  | ||||
|     /** | ||||
|      * 查询代码生成列表 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:list") | ||||
|     @GetMapping("/list") | ||||
|     public TableDataInfo<GenTable> genList(GenTable genTable, PageQuery pageQuery) { | ||||
|         return genTableService.selectPageGenTableList(genTable, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改代码生成业务 | ||||
|      * | ||||
|      * @param tableId 表ID | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:query") | ||||
|     @GetMapping(value = "/{tableId}") | ||||
|     public R<Map<String, Object>> getInfo(@PathVariable Long tableId) { | ||||
|         GenTable table = genTableService.selectGenTableById(tableId); | ||||
|         List<GenTable> tables = genTableService.selectGenTableAll(); | ||||
|         List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId); | ||||
|         Map<String, Object> map = new HashMap<>(3); | ||||
|         map.put("info", table); | ||||
|         map.put("rows", list); | ||||
|         map.put("tables", tables); | ||||
|         return R.ok(map); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询数据库列表 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:list") | ||||
|     @GetMapping("/db/list") | ||||
|     public TableDataInfo<GenTable> dataList(GenTable genTable, PageQuery pageQuery) { | ||||
|         return genTableService.selectPageDbTableList(genTable, pageQuery); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询数据表字段列表 | ||||
|      * | ||||
|      * @param tableId 表ID | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:list") | ||||
|     @GetMapping(value = "/column/{tableId}") | ||||
|     public TableDataInfo<GenTableColumn> columnList(@PathVariable("tableId") Long tableId) { | ||||
|         TableDataInfo<GenTableColumn> dataInfo = new TableDataInfo<>(); | ||||
|         List<GenTableColumn> list = genTableService.selectGenTableColumnListByTableId(tableId); | ||||
|         dataInfo.setRows(list); | ||||
|         dataInfo.setTotal(list.size()); | ||||
|         return dataInfo; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导入表结构(保存) | ||||
|      * | ||||
|      * @param tables 表名串 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:import") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.IMPORT) | ||||
|     @PostMapping("/importTable") | ||||
|     public R<Void> importTableSave(String tables, String dataName) { | ||||
|         String[] tableNames = Convert.toStrArray(tables); | ||||
|         // 查询表信息 | ||||
|         List<GenTable> tableList = genTableService.selectDbTableListByNames(tableNames, dataName); | ||||
|         genTableService.importGenTable(tableList, dataName); | ||||
|         return R.ok(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改保存代码生成业务 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:edit") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.UPDATE) | ||||
|     @PutMapping | ||||
|     public R<Void> editSave(@Validated @RequestBody GenTable genTable) { | ||||
|         genTableService.validateEdit(genTable); | ||||
|         genTableService.updateGenTable(genTable); | ||||
|         return R.ok(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除代码生成 | ||||
|      * | ||||
|      * @param tableIds 表ID串 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:remove") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{tableIds}") | ||||
|     public R<Void> remove(@PathVariable Long[] tableIds) { | ||||
|         genTableService.deleteGenTableByIds(tableIds); | ||||
|         return R.ok(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 预览代码 | ||||
|      * | ||||
|      * @param tableId 表ID | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:preview") | ||||
|     @GetMapping("/preview/{tableId}") | ||||
|     public R<Map<String, String>> preview(@PathVariable("tableId") Long tableId) throws IOException { | ||||
|         Map<String, String> dataMap = genTableService.previewCode(tableId); | ||||
|         return R.ok(dataMap); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 生成代码(下载方式) | ||||
|      * | ||||
|      * @param tableId 表ID | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:code") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.GENCODE) | ||||
|     @GetMapping("/download/{tableId}") | ||||
|     public void download(HttpServletResponse response, @PathVariable("tableId") Long tableId) throws IOException { | ||||
|         byte[] data = genTableService.downloadCode(tableId); | ||||
|         genCode(response, data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 生成代码(自定义路径) | ||||
|      * | ||||
|      * @param tableId 表ID | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:code") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.GENCODE) | ||||
|     @GetMapping("/genCode/{tableId}") | ||||
|     public R<Void> genCode(@PathVariable("tableId") Long tableId) { | ||||
|         genTableService.generatorCode(tableId); | ||||
|         return R.ok(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 同步数据库 | ||||
|      * | ||||
|      * @param tableId 表ID | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:edit") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.UPDATE) | ||||
|     @GetMapping("/synchDb/{tableId}") | ||||
|     public R<Void> synchDb(@PathVariable("tableId") Long tableId) { | ||||
|         genTableService.synchDb(tableId); | ||||
|         return R.ok(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 批量生成代码 | ||||
|      * | ||||
|      * @param tableIdStr 表ID串 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:code") | ||||
|     @Log(title = "代码生成", businessType = BusinessType.GENCODE) | ||||
|     @GetMapping("/batchGenCode") | ||||
|     public void batchGenCode(HttpServletResponse response, String tableIdStr) throws IOException { | ||||
|         String[] tableIds = Convert.toStrArray(tableIdStr); | ||||
|         byte[] data = genTableService.downloadCode(tableIds); | ||||
|         genCode(response, data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 生成zip文件 | ||||
|      */ | ||||
|     private void genCode(HttpServletResponse response, byte[] data) throws IOException { | ||||
|         response.reset(); | ||||
|         response.addHeader("Access-Control-Allow-Origin", "*"); | ||||
|         response.addHeader("Access-Control-Expose-Headers", "Content-Disposition"); | ||||
|         response.setHeader("Content-Disposition", "attachment; filename=\"ruoyi.zip\""); | ||||
|         response.addHeader("Content-Length", "" + data.length); | ||||
|         response.setContentType("application/octet-stream; charset=UTF-8"); | ||||
|         IoUtil.write(response.getOutputStream(), false, data); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询数据源名称列表 | ||||
|      */ | ||||
|     @SaCheckPermission("tool:gen:list") | ||||
|     @GetMapping(value = "/getDataNames") | ||||
|     public R<Object> getCurrentDataSourceNameList(){ | ||||
|         return R.ok(DataBaseHelper.getDataSourceNameList()); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,196 @@ | ||||
| package org.dromara.generator.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.FieldStrategy; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.generator.constant.GenConstants; | ||||
| import jakarta.validation.Valid; | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 业务表 gen_table | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
|  | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("gen_table") | ||||
| public class GenTable extends BaseEntity { | ||||
|  | ||||
|     /** | ||||
|      * 编号 | ||||
|      */ | ||||
|     @TableId(value = "table_id") | ||||
|     private Long tableId; | ||||
|  | ||||
|     /** | ||||
|      * 数据源名称 | ||||
|      */ | ||||
|     @NotBlank(message = "数据源名称不能为空") | ||||
|     private String dataName; | ||||
|  | ||||
|     /** | ||||
|      * 表名称 | ||||
|      */ | ||||
|     @NotBlank(message = "表名称不能为空") | ||||
|     private String tableName; | ||||
|  | ||||
|     /** | ||||
|      * 表描述 | ||||
|      */ | ||||
|     @NotBlank(message = "表描述不能为空") | ||||
|     private String tableComment; | ||||
|  | ||||
|     /** | ||||
|      * 关联父表的表名 | ||||
|      */ | ||||
|     private String subTableName; | ||||
|  | ||||
|     /** | ||||
|      * 本表关联父表的外键名 | ||||
|      */ | ||||
|     private String subTableFkName; | ||||
|  | ||||
|     /** | ||||
|      * 实体类名称(首字母大写) | ||||
|      */ | ||||
|     @NotBlank(message = "实体类名称不能为空") | ||||
|     private String className; | ||||
|  | ||||
|     /** | ||||
|      * 使用的模板(crud单表操作 tree树表操作 sub主子表操作) | ||||
|      */ | ||||
|     private String tplCategory; | ||||
|  | ||||
|     /** | ||||
|      * 生成包路径 | ||||
|      */ | ||||
|     @NotBlank(message = "生成包路径不能为空") | ||||
|     private String packageName; | ||||
|  | ||||
|     /** | ||||
|      * 生成模块名 | ||||
|      */ | ||||
|     @NotBlank(message = "生成模块名不能为空") | ||||
|     private String moduleName; | ||||
|  | ||||
|     /** | ||||
|      * 生成业务名 | ||||
|      */ | ||||
|     @NotBlank(message = "生成业务名不能为空") | ||||
|     private String businessName; | ||||
|  | ||||
|     /** | ||||
|      * 生成功能名 | ||||
|      */ | ||||
|     @NotBlank(message = "生成功能名不能为空") | ||||
|     private String functionName; | ||||
|  | ||||
|     /** | ||||
|      * 生成作者 | ||||
|      */ | ||||
|     @NotBlank(message = "作者不能为空") | ||||
|     private String functionAuthor; | ||||
|  | ||||
|     /** | ||||
|      * 生成代码方式(0zip压缩包 1自定义路径) | ||||
|      */ | ||||
|     private String genType; | ||||
|  | ||||
|     /** | ||||
|      * 生成路径(不填默认项目路径) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.NOT_EMPTY) | ||||
|     private String genPath; | ||||
|  | ||||
|     /** | ||||
|      * 主键信息 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private GenTableColumn pkColumn; | ||||
|  | ||||
|     /** | ||||
|      * 表列信息 | ||||
|      */ | ||||
|     @Valid | ||||
|     @TableField(exist = false) | ||||
|     private List<GenTableColumn> columns; | ||||
|  | ||||
|     /** | ||||
|      * 其它生成选项 | ||||
|      */ | ||||
|     private String options; | ||||
|  | ||||
|     /** | ||||
|      * 备注 | ||||
|      */ | ||||
|     private String remark; | ||||
|  | ||||
|     /** | ||||
|      * 树编码字段 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private String treeCode; | ||||
|  | ||||
|     /** | ||||
|      * 树父编码字段 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private String treeParentCode; | ||||
|  | ||||
|     /** | ||||
|      * 树名称字段 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private String treeName; | ||||
|  | ||||
|     /* | ||||
|      * 菜单id列表 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private List<Long> menuIds; | ||||
|  | ||||
|     /** | ||||
|      * 上级菜单ID字段 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private Long parentMenuId; | ||||
|  | ||||
|     /** | ||||
|      * 上级菜单名称字段 | ||||
|      */ | ||||
|     @TableField(exist = false) | ||||
|     private String parentMenuName; | ||||
|  | ||||
|     public boolean isTree() { | ||||
|         return isTree(this.tplCategory); | ||||
|     } | ||||
|  | ||||
|     public static boolean isTree(String tplCategory) { | ||||
|         return tplCategory != null && StringUtils.equals(GenConstants.TPL_TREE, tplCategory); | ||||
|     } | ||||
|  | ||||
|     public boolean isCrud() { | ||||
|         return isCrud(this.tplCategory); | ||||
|     } | ||||
|  | ||||
|     public static boolean isCrud(String tplCategory) { | ||||
|         return tplCategory != null && StringUtils.equals(GenConstants.TPL_CRUD, tplCategory); | ||||
|     } | ||||
|  | ||||
|     public boolean isSuperColumn(String javaField) { | ||||
|         return isSuperColumn(this.tplCategory, javaField); | ||||
|     } | ||||
|  | ||||
|     public static boolean isSuperColumn(String tplCategory, String javaField) { | ||||
|         return StringUtils.equalsAnyIgnoreCase(javaField, GenConstants.BASE_ENTITY); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,222 @@ | ||||
| package org.dromara.generator.domain; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.FieldStrategy; | ||||
| import com.baomidou.mybatisplus.annotation.TableField; | ||||
| import com.baomidou.mybatisplus.annotation.TableId; | ||||
| import com.baomidou.mybatisplus.annotation.TableName; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import org.apache.ibatis.type.JdbcType; | ||||
|  | ||||
| import jakarta.validation.constraints.NotBlank; | ||||
|  | ||||
| /** | ||||
|  * 代码生成业务字段表 gen_table_column | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("gen_table_column") | ||||
| public class GenTableColumn extends BaseEntity { | ||||
|  | ||||
|     /** | ||||
|      * 编号 | ||||
|      */ | ||||
|     @TableId(value = "column_id") | ||||
|     private Long columnId; | ||||
|  | ||||
|     /** | ||||
|      * 归属表编号 | ||||
|      */ | ||||
|     private Long tableId; | ||||
|  | ||||
|     /** | ||||
|      * 列名称 | ||||
|      */ | ||||
|     private String columnName; | ||||
|  | ||||
|     /** | ||||
|      * 列描述 | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String columnComment; | ||||
|  | ||||
|     /** | ||||
|      * 列类型 | ||||
|      */ | ||||
|     private String columnType; | ||||
|  | ||||
|     /** | ||||
|      * JAVA类型 | ||||
|      */ | ||||
|     private String javaType; | ||||
|  | ||||
|     /** | ||||
|      * JAVA字段名 | ||||
|      */ | ||||
|     @NotBlank(message = "Java属性不能为空") | ||||
|     private String javaField; | ||||
|  | ||||
|     /** | ||||
|      * 是否主键(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isPk; | ||||
|  | ||||
|     /** | ||||
|      * 是否自增(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isIncrement; | ||||
|  | ||||
|     /** | ||||
|      * 是否必填(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isRequired; | ||||
|  | ||||
|     /** | ||||
|      * 是否为插入字段(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isInsert; | ||||
|  | ||||
|     /** | ||||
|      * 是否编辑字段(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isEdit; | ||||
|  | ||||
|     /** | ||||
|      * 是否列表字段(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isList; | ||||
|  | ||||
|     /** | ||||
|      * 是否查询字段(1是) | ||||
|      */ | ||||
|     @TableField(updateStrategy = FieldStrategy.ALWAYS, jdbcType = JdbcType.VARCHAR) | ||||
|     private String isQuery; | ||||
|  | ||||
|     /** | ||||
|      * 查询方式(EQ等于、NE不等于、GT大于、LT小于、LIKE模糊、BETWEEN范围) | ||||
|      */ | ||||
|     private String queryType; | ||||
|  | ||||
|     /** | ||||
|      * 显示类型(input文本框、textarea文本域、select下拉框、checkbox复选框、radio单选框、datetime日期控件、image图片上传控件、upload文件上传控件、editor富文本控件) | ||||
|      */ | ||||
|     private String htmlType; | ||||
|  | ||||
|     /** | ||||
|      * 字典类型 | ||||
|      */ | ||||
|     private String dictType; | ||||
|  | ||||
|     /** | ||||
|      * 排序 | ||||
|      */ | ||||
|     private Integer sort; | ||||
|  | ||||
|     public String getCapJavaField() { | ||||
|         return StringUtils.capitalize(javaField); | ||||
|     } | ||||
|  | ||||
|     public boolean isPk() { | ||||
|         return isPk(this.isPk); | ||||
|     } | ||||
|  | ||||
|     public boolean isPk(String isPk) { | ||||
|         return isPk != null && StringUtils.equals("1", isPk); | ||||
|     } | ||||
|  | ||||
|     public boolean isIncrement() { | ||||
|         return isIncrement(this.isIncrement); | ||||
|     } | ||||
|  | ||||
|     public boolean isIncrement(String isIncrement) { | ||||
|         return isIncrement != null && StringUtils.equals("1", isIncrement); | ||||
|     } | ||||
|  | ||||
|     public boolean isRequired() { | ||||
|         return isRequired(this.isRequired); | ||||
|     } | ||||
|  | ||||
|     public boolean isRequired(String isRequired) { | ||||
|         return isRequired != null && StringUtils.equals("1", isRequired); | ||||
|     } | ||||
|  | ||||
|     public boolean isInsert() { | ||||
|         return isInsert(this.isInsert); | ||||
|     } | ||||
|  | ||||
|     public boolean isInsert(String isInsert) { | ||||
|         return isInsert != null && StringUtils.equals("1", isInsert); | ||||
|     } | ||||
|  | ||||
|     public boolean isEdit() { | ||||
|         return isEdit(this.isEdit); | ||||
|     } | ||||
|  | ||||
|     public boolean isEdit(String isEdit) { | ||||
|         return isEdit != null && StringUtils.equals("1", isEdit); | ||||
|     } | ||||
|  | ||||
|     public boolean isList() { | ||||
|         return isList(this.isList); | ||||
|     } | ||||
|  | ||||
|     public boolean isList(String isList) { | ||||
|         return isList != null && StringUtils.equals("1", isList); | ||||
|     } | ||||
|  | ||||
|     public boolean isQuery() { | ||||
|         return isQuery(this.isQuery); | ||||
|     } | ||||
|  | ||||
|     public boolean isQuery(String isQuery) { | ||||
|         return isQuery != null && StringUtils.equals("1", isQuery); | ||||
|     } | ||||
|  | ||||
|     public boolean isSuperColumn() { | ||||
|         return isSuperColumn(this.javaField); | ||||
|     } | ||||
|  | ||||
|     public static boolean isSuperColumn(String javaField) { | ||||
|         return StringUtils.equalsAnyIgnoreCase(javaField, | ||||
|             // BaseEntity | ||||
|             "createBy", "createTime", "updateBy", "updateTime", | ||||
|             // TreeEntity | ||||
|             "parentName", "parentId"); | ||||
|     } | ||||
|  | ||||
|     public boolean isUsableColumn() { | ||||
|         return isUsableColumn(javaField); | ||||
|     } | ||||
|  | ||||
|     public static boolean isUsableColumn(String javaField) { | ||||
|         // isSuperColumn()中的名单用于避免生成多余Domain属性,若某些属性在生成页面时需要用到不能忽略,则放在此处白名单 | ||||
|         return StringUtils.equalsAnyIgnoreCase(javaField, "parentId", "orderNum", "remark"); | ||||
|     } | ||||
|  | ||||
|     public String readConverterExp() { | ||||
|         String remarks = StringUtils.substringBetween(this.columnComment, "(", ")"); | ||||
|         StringBuffer sb = new StringBuffer(); | ||||
|         if (StringUtils.isNotEmpty(remarks)) { | ||||
|             for (String value : remarks.split(" ")) { | ||||
|                 if (StringUtils.isNotEmpty(value)) { | ||||
|                     Object startStr = value.subSequence(0, 1); | ||||
|                     String endStr = value.substring(1); | ||||
|                     sb.append(StringUtils.EMPTY).append(startStr).append("=").append(endStr).append(StringUtils.SEPARATOR); | ||||
|                 } | ||||
|             } | ||||
|             return sb.deleteCharAt(sb.length() - 1).toString(); | ||||
|         } else { | ||||
|             return this.columnComment; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,15 @@ | ||||
| package org.dromara.generator.mapper; | ||||
|  | ||||
| import com.baomidou.mybatisplus.annotation.InterceptorIgnore; | ||||
| import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; | ||||
| import org.dromara.generator.domain.GenTableColumn; | ||||
|  | ||||
| /** | ||||
|  * 业务字段 数据层 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| @InterceptorIgnore(dataPermission = "true", tenantLine = "true") | ||||
| public interface GenTableColumnMapper extends BaseMapperPlus<GenTableColumn, GenTableColumn> { | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,51 @@ | ||||
| package org.dromara.generator.mapper; | ||||
|  | ||||
| import com.baomidou.dynamic.datasource.annotation.DS; | ||||
| import com.baomidou.mybatisplus.annotation.InterceptorIgnore; | ||||
| import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; | ||||
| import org.dromara.generator.domain.GenTable; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * 业务 数据层 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| @InterceptorIgnore(dataPermission = "true", tenantLine = "true") | ||||
| public interface GenTableMapper extends BaseMapperPlus<GenTable, GenTable> { | ||||
|  | ||||
|     /** | ||||
|      * 查询所有表信息 | ||||
|      * | ||||
|      * @return 表信息集合 | ||||
|      */ | ||||
|     List<GenTable> selectGenTableAll(); | ||||
|  | ||||
|     /** | ||||
|      * 查询表ID业务信息 | ||||
|      * | ||||
|      * @param id 业务ID | ||||
|      * @return 业务信息 | ||||
|      */ | ||||
|     GenTable selectGenTableById(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 查询表名称业务信息 | ||||
|      * | ||||
|      * @param tableName 表名称 | ||||
|      * @return 业务信息 | ||||
|      */ | ||||
|     GenTable selectGenTableByName(String tableName); | ||||
|  | ||||
|     /** | ||||
|      * 查询指定数据源下的所有表名列表 | ||||
|      * | ||||
|      * @param dataName 数据源名称,用于选择不同的数据源 | ||||
|      * @return 当前数据库中的表名列表 | ||||
|      * | ||||
|      * @DS("") 使用默认数据源执行查询操作 | ||||
|      */ | ||||
|     @DS("") | ||||
|     List<String> selectTableNameList(String dataName); | ||||
| } | ||||
| @ -0,0 +1,582 @@ | ||||
| package org.dromara.generator.service; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.io.IoUtil; | ||||
| import cn.hutool.core.lang.Dict; | ||||
| import cn.hutool.core.util.ObjectUtil; | ||||
| import com.baomidou.dynamic.datasource.annotation.DS; | ||||
| import com.baomidou.dynamic.datasource.annotation.DSTransactional; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.incrementer.IdentifierGenerator; | ||||
| import com.baomidou.mybatisplus.core.metadata.IPage; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import lombok.extern.slf4j.Slf4j; | ||||
| import org.anyline.metadata.Column; | ||||
| import org.anyline.metadata.Table; | ||||
| import org.anyline.proxy.ServiceProxy; | ||||
| import org.apache.velocity.Template; | ||||
| import org.apache.velocity.VelocityContext; | ||||
| import org.apache.velocity.app.Velocity; | ||||
| import org.dromara.common.core.constant.Constants; | ||||
| import org.dromara.common.core.exception.ServiceException; | ||||
| import org.dromara.common.core.utils.SpringUtils; | ||||
| import org.dromara.common.core.utils.StreamUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.core.utils.file.FileUtils; | ||||
| import org.dromara.common.json.utils.JsonUtils; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.generator.constant.GenConstants; | ||||
| import org.dromara.generator.domain.GenTable; | ||||
| import org.dromara.generator.domain.GenTableColumn; | ||||
| import org.dromara.generator.mapper.GenTableColumnMapper; | ||||
| import org.dromara.generator.mapper.GenTableMapper; | ||||
| import org.dromara.generator.util.GenUtils; | ||||
| import org.dromara.generator.util.VelocityInitializer; | ||||
| import org.dromara.generator.util.VelocityUtils; | ||||
| import org.springframework.stereotype.Service; | ||||
| import org.springframework.transaction.annotation.Transactional; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.io.StringWriter; | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.util.*; | ||||
| import java.util.zip.ZipEntry; | ||||
| import java.util.zip.ZipOutputStream; | ||||
|  | ||||
| /** | ||||
|  * 业务 服务层实现 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| @Slf4j | ||||
| @RequiredArgsConstructor | ||||
| @Service | ||||
| public class GenTableServiceImpl implements IGenTableService { | ||||
|  | ||||
|     private final GenTableMapper baseMapper; | ||||
|     private final GenTableColumnMapper genTableColumnMapper; | ||||
|     private final IdentifierGenerator identifierGenerator; | ||||
|  | ||||
|     private static final String[] TABLE_IGNORE = new String[]{"sj_", "flow_", "gen_"}; | ||||
|  | ||||
|     /** | ||||
|      * 查询业务字段列表 | ||||
|      * | ||||
|      * @param tableId 业务字段编号 | ||||
|      * @return 业务字段集合 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId) { | ||||
|         return genTableColumnMapper.selectList(new LambdaQueryWrapper<GenTableColumn>() | ||||
|             .eq(GenTableColumn::getTableId, tableId) | ||||
|             .orderByAsc(GenTableColumn::getSort)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询业务信息 | ||||
|      * | ||||
|      * @param id 业务ID | ||||
|      * @return 业务信息 | ||||
|      */ | ||||
|     @Override | ||||
|     public GenTable selectGenTableById(Long id) { | ||||
|         GenTable genTable = baseMapper.selectGenTableById(id); | ||||
|         setTableFromOptions(genTable); | ||||
|         return genTable; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery) { | ||||
|         Page<GenTable> page = baseMapper.selectPage(pageQuery.build(), this.buildGenTableQueryWrapper(genTable)); | ||||
|         return TableDataInfo.build(page); | ||||
|     } | ||||
|  | ||||
|     private QueryWrapper<GenTable> buildGenTableQueryWrapper(GenTable genTable) { | ||||
|         Map<String, Object> params = genTable.getParams(); | ||||
|         QueryWrapper<GenTable> wrapper = Wrappers.query(); | ||||
|         wrapper | ||||
|             .eq(StringUtils.isNotEmpty(genTable.getDataName()), "data_name", genTable.getDataName()) | ||||
|             .like(StringUtils.isNotBlank(genTable.getTableName()), "lower(table_name)", StringUtils.lowerCase(genTable.getTableName())) | ||||
|             .like(StringUtils.isNotBlank(genTable.getTableComment()), "lower(table_comment)", StringUtils.lowerCase(genTable.getTableComment())) | ||||
|             .between(params.get("beginTime") != null && params.get("endTime") != null, | ||||
|                 "create_time", params.get("beginTime"), params.get("endTime")) | ||||
|             .orderByDesc("update_time"); | ||||
|         return wrapper; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询数据库列表 | ||||
|      * | ||||
|      * @param genTable  包含查询条件的GenTable对象 | ||||
|      * @param pageQuery 包含分页信息的PageQuery对象 | ||||
|      * @return 包含分页结果的TableDataInfo对象 | ||||
|      */ | ||||
|     @DS("#genTable.dataName") | ||||
|     @Override | ||||
|     public TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery) { | ||||
|         // 获取查询条件 | ||||
|         String tableName = genTable.getTableName(); | ||||
|         String tableComment = genTable.getTableComment(); | ||||
|  | ||||
|         LinkedHashMap<String, Table<?>> tablesMap = ServiceProxy.metadata().tables(); | ||||
|         if (CollUtil.isEmpty(tablesMap)) { | ||||
|             return TableDataInfo.build(); | ||||
|         } | ||||
|         List<String> tableNames = baseMapper.selectTableNameList(genTable.getDataName()); | ||||
|         String[] tableArrays; | ||||
|         if (CollUtil.isNotEmpty(tableNames)) { | ||||
|             tableArrays = tableNames.toArray(new String[0]); | ||||
|         } else { | ||||
|             tableArrays = new String[0]; | ||||
|         } | ||||
|         // 过滤并转换表格数据 | ||||
|         List<GenTable> tables = tablesMap.values().stream() | ||||
|             .filter(x -> !StringUtils.startWithAnyIgnoreCase(x.getName(), TABLE_IGNORE)) | ||||
|             .filter(x -> { | ||||
|                 if (CollUtil.isEmpty(tableNames)) { | ||||
|                     return true; | ||||
|                 } | ||||
|                 return !StringUtils.equalsAnyIgnoreCase(x.getName(), tableArrays); | ||||
|             }) | ||||
|             .filter(x -> { | ||||
|                 boolean nameMatches = true; | ||||
|                 boolean commentMatches = true; | ||||
|                 // 进行表名称的模糊查询 | ||||
|                 if (StringUtils.isNotBlank(tableName)) { | ||||
|                     nameMatches = StringUtils.containsIgnoreCase(x.getName(), tableName); | ||||
|                 } | ||||
|                 // 进行表描述的模糊查询 | ||||
|                 if (StringUtils.isNotBlank(tableComment)) { | ||||
|                     commentMatches = StringUtils.containsIgnoreCase(x.getComment(), tableComment); | ||||
|                 } | ||||
|                 // 同时匹配名称和描述 | ||||
|                 return nameMatches && commentMatches; | ||||
|             }) | ||||
|             .map(x -> { | ||||
|                 GenTable gen = new GenTable(); | ||||
|                 gen.setTableName(x.getName()); | ||||
|                 gen.setTableComment(x.getComment()); | ||||
|                 // postgresql的表元数据没有创建时间这个东西(好奇葩) 只能new Date代替 | ||||
|                 gen.setCreateTime(ObjectUtil.defaultIfNull(x.getCreateTime(), new Date())); | ||||
|                 gen.setUpdateTime(x.getUpdateTime()); | ||||
|                 return gen; | ||||
|             }).sorted(Comparator.comparing(GenTable::getCreateTime).reversed()) | ||||
|             .toList(); | ||||
|  | ||||
|         IPage<GenTable> page = pageQuery.build(); | ||||
|         page.setTotal(tables.size()); | ||||
|         // 手动分页 set数据 | ||||
|         page.setRecords(CollUtil.page((int) page.getCurrent() - 1, (int) page.getSize(), tables)); | ||||
|         return TableDataInfo.build(page); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询据库列表 | ||||
|      * | ||||
|      * @param tableNames 表名称组 | ||||
|      * @param dataName   数据源名称 | ||||
|      * @return 数据库表集合 | ||||
|      */ | ||||
|     @DS("#dataName") | ||||
|     @Override | ||||
|     public List<GenTable> selectDbTableListByNames(String[] tableNames, String dataName) { | ||||
|         Set<String> tableNameSet = new HashSet<>(List.of(tableNames)); | ||||
|         LinkedHashMap<String, Table<?>> tablesMap = ServiceProxy.metadata().tables(); | ||||
|  | ||||
|         if (CollUtil.isEmpty(tablesMap)) { | ||||
|             return new ArrayList<>(); | ||||
|         } | ||||
|  | ||||
|         List<Table<?>> tableList = tablesMap.values().stream() | ||||
|             .filter(x -> !StringUtils.startWithAnyIgnoreCase(x.getName(), TABLE_IGNORE)) | ||||
|             .filter(x -> tableNameSet.contains(x.getName())).toList(); | ||||
|  | ||||
|         if (CollUtil.isEmpty(tableList)) { | ||||
|             return new ArrayList<>(); | ||||
|         } | ||||
|         return tableList.stream().map(x -> { | ||||
|             GenTable gen = new GenTable(); | ||||
|             gen.setDataName(dataName); | ||||
|             gen.setTableName(x.getName()); | ||||
|             gen.setTableComment(x.getComment()); | ||||
|             gen.setCreateTime(x.getCreateTime()); | ||||
|             gen.setUpdateTime(x.getUpdateTime()); | ||||
|             return gen; | ||||
|         }).toList(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询所有表信息 | ||||
|      * | ||||
|      * @return 表信息集合 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<GenTable> selectGenTableAll() { | ||||
|         return baseMapper.selectGenTableAll(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改业务 | ||||
|      * | ||||
|      * @param genTable 业务信息 | ||||
|      */ | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @Override | ||||
|     public void updateGenTable(GenTable genTable) { | ||||
|         String options = JsonUtils.toJsonString(genTable.getParams()); | ||||
|         genTable.setOptions(options); | ||||
|         int row = baseMapper.updateById(genTable); | ||||
|         if (row > 0) { | ||||
|             for (GenTableColumn cenTableColumn : genTable.getColumns()) { | ||||
|                 genTableColumnMapper.updateById(cenTableColumn); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除业务对象 | ||||
|      * | ||||
|      * @param tableIds 需要删除的数据ID | ||||
|      */ | ||||
|     @Transactional(rollbackFor = Exception.class) | ||||
|     @Override | ||||
|     public void deleteGenTableByIds(Long[] tableIds) { | ||||
|         List<Long> ids = Arrays.asList(tableIds); | ||||
|         baseMapper.deleteByIds(ids); | ||||
|         genTableColumnMapper.delete(new LambdaQueryWrapper<GenTableColumn>().in(GenTableColumn::getTableId, ids)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 导入表结构 | ||||
|      * | ||||
|      * @param tableList 导入表列表 | ||||
|      * @param dataName  数据源名称 | ||||
|      */ | ||||
|     @DSTransactional | ||||
|     @Override | ||||
|     public void importGenTable(List<GenTable> tableList, String dataName) { | ||||
|         try { | ||||
|             for (GenTable table : tableList) { | ||||
|                 String tableName = table.getTableName(); | ||||
|                 GenUtils.initTable(table); | ||||
|                 table.setDataName(dataName); | ||||
|                 int row = baseMapper.insert(table); | ||||
|                 if (row > 0) { | ||||
|                     // 保存列信息 | ||||
|                     List<GenTableColumn> genTableColumns = SpringUtils.getAopProxy(this).selectDbTableColumnsByName(tableName, dataName); | ||||
|                     List<GenTableColumn> saveColumns = new ArrayList<>(); | ||||
|                     for (GenTableColumn column : genTableColumns) { | ||||
|                         GenUtils.initColumnField(column, table); | ||||
|                         saveColumns.add(column); | ||||
|                     } | ||||
|                     if (CollUtil.isNotEmpty(saveColumns)) { | ||||
|                         genTableColumnMapper.insertBatch(saveColumns); | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|         } catch (Exception e) { | ||||
|             throw new ServiceException("导入失败:" + e.getMessage()); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据表名称查询列信息 | ||||
|      * | ||||
|      * @param tableName 表名称 | ||||
|      * @param dataName  数据源名称 | ||||
|      * @return 列信息 | ||||
|      */ | ||||
|     @DS("#dataName") | ||||
|     @Override | ||||
|     public List<GenTableColumn> selectDbTableColumnsByName(String tableName, String dataName) { | ||||
|         Table<?> table = ServiceProxy.metadata().table(tableName); | ||||
|         if (ObjectUtil.isNull(table)) { | ||||
|             return new ArrayList<>(); | ||||
|         } | ||||
|         LinkedHashMap<String, Column> columns = table.getColumns(); | ||||
|         List<GenTableColumn> tableColumns = new ArrayList<>(); | ||||
|         columns.forEach((columnName, column) -> { | ||||
|             GenTableColumn tableColumn = new GenTableColumn(); | ||||
|             tableColumn.setIsPk(String.valueOf(column.isPrimaryKey())); | ||||
|             tableColumn.setColumnName(column.getName()); | ||||
|             tableColumn.setColumnComment(column.getComment()); | ||||
|             tableColumn.setColumnType(column.getOriginType().toLowerCase()); | ||||
|             tableColumn.setSort(column.getPosition()); | ||||
|             tableColumn.setIsRequired(column.isNullable() == 0 ? "1" : "0"); | ||||
|             tableColumn.setIsIncrement(column.isAutoIncrement() == -1 ? "0" : "1"); | ||||
|             tableColumns.add(tableColumn); | ||||
|         }); | ||||
|         return tableColumns; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 预览代码 | ||||
|      * | ||||
|      * @param tableId 表编号 | ||||
|      * @return 预览数据列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public Map<String, String> previewCode(Long tableId) { | ||||
|         Map<String, String> dataMap = new LinkedHashMap<>(); | ||||
|         // 查询表信息 | ||||
|         GenTable table = baseMapper.selectGenTableById(tableId); | ||||
|         List<Long> menuIds = new ArrayList<>(); | ||||
|         for (int i = 0; i < 6; i++) { | ||||
|             menuIds.add(identifierGenerator.nextId(null).longValue()); | ||||
|         } | ||||
|         table.setMenuIds(menuIds); | ||||
|         // 设置主键列信息 | ||||
|         setPkColumn(table); | ||||
|         VelocityInitializer.initVelocity(); | ||||
|  | ||||
|         VelocityContext context = VelocityUtils.prepareContext(table); | ||||
|  | ||||
|         // 获取模板列表 | ||||
|         List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); | ||||
|         for (String template : templates) { | ||||
|             // 渲染模板 | ||||
|             StringWriter sw = new StringWriter(); | ||||
|             Template tpl = Velocity.getTemplate(template, Constants.UTF8); | ||||
|             tpl.merge(context, sw); | ||||
|             dataMap.put(template, sw.toString()); | ||||
|         } | ||||
|         return dataMap; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 生成代码(下载方式) | ||||
|      * | ||||
|      * @param tableId 表名称 | ||||
|      * @return 数据 | ||||
|      */ | ||||
|     @Override | ||||
|     public byte[] downloadCode(Long tableId) { | ||||
|         ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ||||
|         ZipOutputStream zip = new ZipOutputStream(outputStream); | ||||
|         generatorCode(tableId, zip); | ||||
|         IoUtil.close(zip); | ||||
|         return outputStream.toByteArray(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 生成代码(自定义路径) | ||||
|      * | ||||
|      * @param tableId 表名称 | ||||
|      */ | ||||
|     @Override | ||||
|     public void generatorCode(Long tableId) { | ||||
|         // 查询表信息 | ||||
|         GenTable table = baseMapper.selectGenTableById(tableId); | ||||
|         // 设置主键列信息 | ||||
|         setPkColumn(table); | ||||
|  | ||||
|         VelocityInitializer.initVelocity(); | ||||
|  | ||||
|         VelocityContext context = VelocityUtils.prepareContext(table); | ||||
|  | ||||
|         // 获取模板列表 | ||||
|         List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); | ||||
|         for (String template : templates) { | ||||
|             if (!StringUtils.containsAny(template, "sql.vm", "api.ts.vm", "types.ts.vm", "index.vue.vm", "index-tree.vue.vm")) { | ||||
|                 // 渲染模板 | ||||
|                 StringWriter sw = new StringWriter(); | ||||
|                 Template tpl = Velocity.getTemplate(template, Constants.UTF8); | ||||
|                 tpl.merge(context, sw); | ||||
|                 try { | ||||
|                     String path = getGenPath(table, template); | ||||
|                     FileUtils.writeUtf8String(sw.toString(), path); | ||||
|                 } catch (Exception e) { | ||||
|                     throw new ServiceException("渲染模板失败,表名:" + table.getTableName()); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 同步数据库 | ||||
|      * | ||||
|      * @param tableId 表名称 | ||||
|      */ | ||||
|     @DSTransactional | ||||
|     @Override | ||||
|     public void synchDb(Long tableId) { | ||||
|         GenTable table = baseMapper.selectGenTableById(tableId); | ||||
|         List<GenTableColumn> tableColumns = table.getColumns(); | ||||
|         Map<String, GenTableColumn> tableColumnMap = StreamUtils.toIdentityMap(tableColumns, GenTableColumn::getColumnName); | ||||
|  | ||||
|         List<GenTableColumn> dbTableColumns = SpringUtils.getAopProxy(this).selectDbTableColumnsByName(table.getTableName(), table.getDataName()); | ||||
|         if (CollUtil.isEmpty(dbTableColumns)) { | ||||
|             throw new ServiceException("同步数据失败,原表结构不存在"); | ||||
|         } | ||||
|         List<String> dbTableColumnNames = StreamUtils.toList(dbTableColumns, GenTableColumn::getColumnName); | ||||
|  | ||||
|         List<GenTableColumn> saveColumns = new ArrayList<>(); | ||||
|         dbTableColumns.forEach(column -> { | ||||
|             GenUtils.initColumnField(column, table); | ||||
|             if (tableColumnMap.containsKey(column.getColumnName())) { | ||||
|                 GenTableColumn prevColumn = tableColumnMap.get(column.getColumnName()); | ||||
|                 column.setColumnId(prevColumn.getColumnId()); | ||||
|                 if (column.isList()) { | ||||
|                     // 如果是列表,继续保留查询方式/字典类型选项 | ||||
|                     column.setDictType(prevColumn.getDictType()); | ||||
|                     column.setQueryType(prevColumn.getQueryType()); | ||||
|                 } | ||||
|                 if (StringUtils.isNotEmpty(prevColumn.getIsRequired()) && !column.isPk() | ||||
|                     && (column.isInsert() || column.isEdit()) | ||||
|                     && ((column.isUsableColumn()) || (!column.isSuperColumn()))) { | ||||
|                     // 如果是(新增/修改&非主键/非忽略及父属性),继续保留必填/显示类型选项 | ||||
|                     column.setIsRequired(prevColumn.getIsRequired()); | ||||
|                     column.setHtmlType(prevColumn.getHtmlType()); | ||||
|                 } | ||||
|             } | ||||
|             saveColumns.add(column); | ||||
|         }); | ||||
|         if (CollUtil.isNotEmpty(saveColumns)) { | ||||
|             genTableColumnMapper.insertOrUpdateBatch(saveColumns); | ||||
|         } | ||||
|         List<GenTableColumn> delColumns = StreamUtils.filter(tableColumns, column -> !dbTableColumnNames.contains(column.getColumnName())); | ||||
|         if (CollUtil.isNotEmpty(delColumns)) { | ||||
|             List<Long> ids = StreamUtils.toList(delColumns, GenTableColumn::getColumnId); | ||||
|             if (CollUtil.isNotEmpty(ids)) { | ||||
|                 genTableColumnMapper.deleteByIds(ids); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 批量生成代码(下载方式) | ||||
|      * | ||||
|      * @param tableIds 表ID数组 | ||||
|      * @return 数据 | ||||
|      */ | ||||
|     @Override | ||||
|     public byte[] downloadCode(String[] tableIds) { | ||||
|         ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); | ||||
|         ZipOutputStream zip = new ZipOutputStream(outputStream); | ||||
|         for (String tableId : tableIds) { | ||||
|             generatorCode(Long.parseLong(tableId), zip); | ||||
|         } | ||||
|         IoUtil.close(zip); | ||||
|         return outputStream.toByteArray(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 查询表信息并生成代码 | ||||
|      */ | ||||
|     private void generatorCode(Long tableId, ZipOutputStream zip) { | ||||
|         // 查询表信息 | ||||
|         GenTable table = baseMapper.selectGenTableById(tableId); | ||||
|         List<Long> menuIds = new ArrayList<>(); | ||||
|         for (int i = 0; i < 6; i++) { | ||||
|             menuIds.add(identifierGenerator.nextId(null).longValue()); | ||||
|         } | ||||
|         table.setMenuIds(menuIds); | ||||
|         // 设置主键列信息 | ||||
|         setPkColumn(table); | ||||
|  | ||||
|         VelocityInitializer.initVelocity(); | ||||
|  | ||||
|         VelocityContext context = VelocityUtils.prepareContext(table); | ||||
|  | ||||
|         // 获取模板列表 | ||||
|         List<String> templates = VelocityUtils.getTemplateList(table.getTplCategory()); | ||||
|         for (String template : templates) { | ||||
|             // 渲染模板 | ||||
|             StringWriter sw = new StringWriter(); | ||||
|             Template tpl = Velocity.getTemplate(template, Constants.UTF8); | ||||
|             tpl.merge(context, sw); | ||||
|             try { | ||||
|                 // 添加到zip | ||||
|                 zip.putNextEntry(new ZipEntry(VelocityUtils.getFileName(template, table))); | ||||
|                 IoUtil.write(zip, StandardCharsets.UTF_8, false, sw.toString()); | ||||
|                 IoUtil.close(sw); | ||||
|                 zip.flush(); | ||||
|                 zip.closeEntry(); | ||||
|             } catch (IOException e) { | ||||
|                 log.error("渲染模板失败,表名:" + table.getTableName(), e); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改保存参数校验 | ||||
|      * | ||||
|      * @param genTable 业务信息 | ||||
|      */ | ||||
|     @Override | ||||
|     public void validateEdit(GenTable genTable) { | ||||
|         if (GenConstants.TPL_TREE.equals(genTable.getTplCategory())) { | ||||
|             String options = JsonUtils.toJsonString(genTable.getParams()); | ||||
|             Dict paramsObj = JsonUtils.parseMap(options); | ||||
|             if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_CODE))) { | ||||
|                 throw new ServiceException("树编码字段不能为空"); | ||||
|             } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_PARENT_CODE))) { | ||||
|                 throw new ServiceException("树父编码字段不能为空"); | ||||
|             } else if (StringUtils.isEmpty(paramsObj.getStr(GenConstants.TREE_NAME))) { | ||||
|                 throw new ServiceException("树名称字段不能为空"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 设置主键列信息 | ||||
|      * | ||||
|      * @param table 业务表信息 | ||||
|      */ | ||||
|     public void setPkColumn(GenTable table) { | ||||
|         for (GenTableColumn column : table.getColumns()) { | ||||
|             if (column.isPk()) { | ||||
|                 table.setPkColumn(column); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         if (ObjectUtil.isNull(table.getPkColumn())) { | ||||
|             table.setPkColumn(table.getColumns().get(0)); | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 设置代码生成其他选项值 | ||||
|      * | ||||
|      * @param genTable 设置后的生成对象 | ||||
|      */ | ||||
|     public void setTableFromOptions(GenTable genTable) { | ||||
|         Dict paramsObj = JsonUtils.parseMap(genTable.getOptions()); | ||||
|         if (ObjectUtil.isNotNull(paramsObj)) { | ||||
|             String treeCode = paramsObj.getStr(GenConstants.TREE_CODE); | ||||
|             String treeParentCode = paramsObj.getStr(GenConstants.TREE_PARENT_CODE); | ||||
|             String treeName = paramsObj.getStr(GenConstants.TREE_NAME); | ||||
|             Long parentMenuId = paramsObj.getLong(GenConstants.PARENT_MENU_ID); | ||||
|             String parentMenuName = paramsObj.getStr(GenConstants.PARENT_MENU_NAME); | ||||
|  | ||||
|             genTable.setTreeCode(treeCode); | ||||
|             genTable.setTreeParentCode(treeParentCode); | ||||
|             genTable.setTreeName(treeName); | ||||
|             genTable.setParentMenuId(parentMenuId); | ||||
|             genTable.setParentMenuName(parentMenuName); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取代码生成地址 | ||||
|      * | ||||
|      * @param table    业务表信息 | ||||
|      * @param template 模板文件路径 | ||||
|      * @return 生成地址 | ||||
|      */ | ||||
|     public static String getGenPath(GenTable table, String template) { | ||||
|         String genPath = table.getGenPath(); | ||||
|         if (StringUtils.equals(genPath, "/")) { | ||||
|             return System.getProperty("user.dir") + File.separator + "src" + File.separator + VelocityUtils.getFileName(template, table); | ||||
|         } | ||||
|         return genPath + File.separator + VelocityUtils.getFileName(template, table); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,141 @@ | ||||
| package org.dromara.generator.service; | ||||
|  | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.generator.domain.GenTable; | ||||
| import org.dromara.generator.domain.GenTableColumn; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| /** | ||||
|  * 业务 服务层 | ||||
|  * | ||||
|  * @author Lion Li | ||||
|  */ | ||||
| public interface IGenTableService { | ||||
|  | ||||
|     /** | ||||
|      * 查询业务字段列表 | ||||
|      * | ||||
|      * @param tableId 业务字段编号 | ||||
|      * @return 业务字段集合 | ||||
|      */ | ||||
|     List<GenTableColumn> selectGenTableColumnListByTableId(Long tableId); | ||||
|  | ||||
|     /** | ||||
|      * 查询业务列表 | ||||
|      * | ||||
|      * @param genTable 业务信息 | ||||
|      * @return 业务集合 | ||||
|      */ | ||||
|     TableDataInfo<GenTable> selectPageGenTableList(GenTable genTable, PageQuery pageQuery); | ||||
|  | ||||
|     /** | ||||
|      * 查询据库列表 | ||||
|      * | ||||
|      * @param genTable 业务信息 | ||||
|      * @return 数据库表集合 | ||||
|      */ | ||||
|     TableDataInfo<GenTable> selectPageDbTableList(GenTable genTable, PageQuery pageQuery); | ||||
|  | ||||
|     /** | ||||
|      * 查询据库列表 | ||||
|      * | ||||
|      * @param tableNames 表名称组 | ||||
|      * @param dataName   数据源名称 | ||||
|      * @return 数据库表集合 | ||||
|      */ | ||||
|     List<GenTable> selectDbTableListByNames(String[] tableNames, String dataName); | ||||
|  | ||||
|     /** | ||||
|      * 查询所有表信息 | ||||
|      * | ||||
|      * @return 表信息集合 | ||||
|      */ | ||||
|     List<GenTable> selectGenTableAll(); | ||||
|  | ||||
|     /** | ||||
|      * 查询业务信息 | ||||
|      * | ||||
|      * @param id 业务ID | ||||
|      * @return 业务信息 | ||||
|      */ | ||||
|     GenTable selectGenTableById(Long id); | ||||
|  | ||||
|     /** | ||||
|      * 修改业务 | ||||
|      * | ||||
|      * @param genTable 业务信息 | ||||
|      */ | ||||
|     void updateGenTable(GenTable genTable); | ||||
|  | ||||
|     /** | ||||
|      * 删除业务信息 | ||||
|      * | ||||
|      * @param tableIds 需要删除的表数据ID | ||||
|      */ | ||||
|     void deleteGenTableByIds(Long[] tableIds); | ||||
|  | ||||
|     /** | ||||
|      * 导入表结构 | ||||
|      * | ||||
|      * @param tableList 导入表列表 | ||||
|      * @param dataName  数据源名称 | ||||
|      */ | ||||
|     void importGenTable(List<GenTable> tableList, String dataName); | ||||
|  | ||||
|     /** | ||||
|      * 根据表名称查询列信息 | ||||
|      * | ||||
|      * @param tableName 表名称 | ||||
|      * @param dataName  数据源名称 | ||||
|      * @return 列信息 | ||||
|      */ | ||||
|     List<GenTableColumn> selectDbTableColumnsByName(String tableName, String dataName); | ||||
|  | ||||
|     /** | ||||
|      * 预览代码 | ||||
|      * | ||||
|      * @param tableId 表编号 | ||||
|      * @return 预览数据列表 | ||||
|      */ | ||||
|     Map<String, String> previewCode(Long tableId); | ||||
|  | ||||
|     /** | ||||
|      * 生成代码(下载方式) | ||||
|      * | ||||
|      * @param tableId 表名称 | ||||
|      * @return 数据 | ||||
|      */ | ||||
|     byte[] downloadCode(Long tableId); | ||||
|  | ||||
|     /** | ||||
|      * 生成代码(自定义路径) | ||||
|      * | ||||
|      * @param tableId 表名称 | ||||
|      */ | ||||
|     void generatorCode(Long tableId); | ||||
|  | ||||
|     /** | ||||
|      * 同步数据库 | ||||
|      * | ||||
|      * @param tableId 表名称 | ||||
|      */ | ||||
|     void synchDb(Long tableId); | ||||
|  | ||||
|     /** | ||||
|      * 批量生成代码(下载方式) | ||||
|      * | ||||
|      * @param tableIds 表ID数组 | ||||
|      * @return 数据 | ||||
|      */ | ||||
|     byte[] downloadCode(String[] tableIds); | ||||
|  | ||||
|     /** | ||||
|      * 修改保存参数校验 | ||||
|      * | ||||
|      * @param genTable 业务信息 | ||||
|      */ | ||||
|     void validateEdit(GenTable genTable); | ||||
| } | ||||
| @ -0,0 +1,219 @@ | ||||
| package org.dromara.generator.util; | ||||
|  | ||||
| import lombok.AccessLevel; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.apache.commons.lang3.RegExUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.generator.config.GenConfig; | ||||
| import org.dromara.generator.constant.GenConstants; | ||||
| import org.dromara.generator.domain.GenTable; | ||||
| import org.dromara.generator.domain.GenTableColumn; | ||||
|  | ||||
| import java.util.Arrays; | ||||
|  | ||||
| /** | ||||
|  * 代码生成器 工具类 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class GenUtils { | ||||
|  | ||||
|     /** | ||||
|      * 初始化表信息 | ||||
|      */ | ||||
|     public static void initTable(GenTable genTable) { | ||||
|         genTable.setClassName(convertClassName(genTable.getTableName())); | ||||
|         genTable.setPackageName(GenConfig.getPackageName()); | ||||
|         genTable.setModuleName(getModuleName(GenConfig.getPackageName())); | ||||
|         genTable.setBusinessName(getBusinessName(genTable.getTableName())); | ||||
|         genTable.setFunctionName(replaceText(genTable.getTableComment())); | ||||
|         genTable.setFunctionAuthor(GenConfig.getAuthor()); | ||||
|         genTable.setCreateTime(null); | ||||
|         genTable.setUpdateTime(null); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 初始化列属性字段 | ||||
|      */ | ||||
|     public static void initColumnField(GenTableColumn column, GenTable table) { | ||||
|         String dataType = getDbType(column.getColumnType()); | ||||
|         // 统一转小写 避免有些数据库默认大写问题 如果需要特别书写方式 请在实体类增加注解标注别名 | ||||
|         String columnName = column.getColumnName().toLowerCase(); | ||||
|         column.setTableId(table.getTableId()); | ||||
|         column.setCreateTime(null); | ||||
|         column.setUpdateTime(null); | ||||
|         // 设置java字段名 | ||||
|         column.setJavaField(StringUtils.toCamelCase(columnName)); | ||||
|         // 设置默认类型 | ||||
|         column.setJavaType(GenConstants.TYPE_STRING); | ||||
|         column.setQueryType(GenConstants.QUERY_EQ); | ||||
|  | ||||
|         if (arraysContains(GenConstants.COLUMNTYPE_STR, dataType) || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType)) { | ||||
|             // 字符串长度超过500设置为文本域 | ||||
|             Integer columnLength = getColumnLength(column.getColumnType()); | ||||
|             String htmlType = columnLength >= 500 || arraysContains(GenConstants.COLUMNTYPE_TEXT, dataType) ? GenConstants.HTML_TEXTAREA : GenConstants.HTML_INPUT; | ||||
|             column.setHtmlType(htmlType); | ||||
|         } else if (arraysContains(GenConstants.COLUMNTYPE_TIME, dataType)) { | ||||
|             column.setJavaType(GenConstants.TYPE_DATE); | ||||
|             column.setHtmlType(GenConstants.HTML_DATETIME); | ||||
|         } else if (arraysContains(GenConstants.COLUMNTYPE_NUMBER, dataType)) { | ||||
|             column.setHtmlType(GenConstants.HTML_INPUT); | ||||
|             // 数据库的数字字段与java不匹配 且很多数据库的数字字段很模糊 例如oracle只有number没有细分 | ||||
|             // 所以默认数字类型全为Long可在界面上自行编辑想要的类型 有什么特殊需求也可以在这里特殊处理 | ||||
|             column.setJavaType(GenConstants.TYPE_LONG); | ||||
|         } | ||||
|  | ||||
|         // BO对象 默认插入勾选 | ||||
|         if (!arraysContains(GenConstants.COLUMNNAME_NOT_ADD, columnName) && !column.isPk()) { | ||||
|             column.setIsInsert(GenConstants.REQUIRE); | ||||
|         } | ||||
|         // BO对象 默认编辑勾选 | ||||
|         if (!arraysContains(GenConstants.COLUMNNAME_NOT_EDIT, columnName)) { | ||||
|             column.setIsEdit(GenConstants.REQUIRE); | ||||
|         } | ||||
|         // VO对象 默认返回勾选 | ||||
|         if (!arraysContains(GenConstants.COLUMNNAME_NOT_LIST, columnName)) { | ||||
|             column.setIsList(GenConstants.REQUIRE); | ||||
|         } | ||||
|         // BO对象 默认查询勾选 | ||||
|         if (!arraysContains(GenConstants.COLUMNNAME_NOT_QUERY, columnName) && !column.isPk()) { | ||||
|             column.setIsQuery(GenConstants.REQUIRE); | ||||
|         } | ||||
|  | ||||
|         // 查询字段类型 | ||||
|         if (StringUtils.endsWithIgnoreCase(columnName, "name")) { | ||||
|             column.setQueryType(GenConstants.QUERY_LIKE); | ||||
|         } | ||||
|         // 状态字段设置单选框 | ||||
|         if (StringUtils.endsWithIgnoreCase(columnName, "status")) { | ||||
|             column.setHtmlType(GenConstants.HTML_RADIO); | ||||
|         } | ||||
|         // 类型&性别字段设置下拉框 | ||||
|         else if (StringUtils.endsWithIgnoreCase(columnName, "type") | ||||
|             || StringUtils.endsWithIgnoreCase(columnName, "sex")) { | ||||
|             column.setHtmlType(GenConstants.HTML_SELECT); | ||||
|         } | ||||
|         // 图片字段设置图片上传控件 | ||||
|         else if (StringUtils.endsWithIgnoreCase(columnName, "image")) { | ||||
|             column.setHtmlType(GenConstants.HTML_IMAGE_UPLOAD); | ||||
|         } | ||||
|         // 文件字段设置文件上传控件 | ||||
|         else if (StringUtils.endsWithIgnoreCase(columnName, "file")) { | ||||
|             column.setHtmlType(GenConstants.HTML_FILE_UPLOAD); | ||||
|         } | ||||
|         // 内容字段设置富文本控件 | ||||
|         else if (StringUtils.endsWithIgnoreCase(columnName, "content")) { | ||||
|             column.setHtmlType(GenConstants.HTML_EDITOR); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 校验数组是否包含指定值 | ||||
|      * | ||||
|      * @param arr         数组 | ||||
|      * @param targetValue 值 | ||||
|      * @return 是否包含 | ||||
|      */ | ||||
|     public static boolean arraysContains(String[] arr, String targetValue) { | ||||
|         return Arrays.asList(arr).contains(targetValue); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取模块名 | ||||
|      * | ||||
|      * @param packageName 包名 | ||||
|      * @return 模块名 | ||||
|      */ | ||||
|     public static String getModuleName(String packageName) { | ||||
|         int lastIndex = packageName.lastIndexOf("."); | ||||
|         int nameLength = packageName.length(); | ||||
|         return StringUtils.substring(packageName, lastIndex + 1, nameLength); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取业务名 | ||||
|      * | ||||
|      * @param tableName 表名 | ||||
|      * @return 业务名 | ||||
|      */ | ||||
|     public static String getBusinessName(String tableName) { | ||||
|         int firstIndex = tableName.indexOf("_"); | ||||
|         int nameLength = tableName.length(); | ||||
|         String businessName = StringUtils.substring(tableName, firstIndex + 1, nameLength); | ||||
|         businessName = StringUtils.toCamelCase(businessName); | ||||
|         return businessName; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 表名转换成Java类名 | ||||
|      * | ||||
|      * @param tableName 表名称 | ||||
|      * @return 类名 | ||||
|      */ | ||||
|     public static String convertClassName(String tableName) { | ||||
|         boolean autoRemovePre = GenConfig.getAutoRemovePre(); | ||||
|         String tablePrefix = GenConfig.getTablePrefix(); | ||||
|         if (autoRemovePre && StringUtils.isNotEmpty(tablePrefix)) { | ||||
|             String[] searchList = StringUtils.split(tablePrefix, StringUtils.SEPARATOR); | ||||
|             tableName = replaceFirst(tableName, searchList); | ||||
|         } | ||||
|         return StringUtils.convertToCamelCase(tableName); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 批量替换前缀 | ||||
|      * | ||||
|      * @param replacementm 替换值 | ||||
|      * @param searchList   替换列表 | ||||
|      */ | ||||
|     public static String replaceFirst(String replacementm, String[] searchList) { | ||||
|         String text = replacementm; | ||||
|         for (String searchString : searchList) { | ||||
|             if (replacementm.startsWith(searchString)) { | ||||
|                 text = replacementm.replaceFirst(searchString, StringUtils.EMPTY); | ||||
|                 break; | ||||
|             } | ||||
|         } | ||||
|         return text; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 关键字替换 | ||||
|      * | ||||
|      * @param text 需要被替换的名字 | ||||
|      * @return 替换后的名字 | ||||
|      */ | ||||
|     public static String replaceText(String text) { | ||||
|         return RegExUtils.replaceAll(text, "(?:表|若依)", ""); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取数据库类型字段 | ||||
|      * | ||||
|      * @param columnType 列类型 | ||||
|      * @return 截取后的列类型 | ||||
|      */ | ||||
|     public static String getDbType(String columnType) { | ||||
|         if (StringUtils.indexOf(columnType, "(") > 0) { | ||||
|             return StringUtils.substringBefore(columnType, "("); | ||||
|         } else { | ||||
|             return columnType; | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取字段长度 | ||||
|      * | ||||
|      * @param columnType 列类型 | ||||
|      * @return 截取后的列类型 | ||||
|      */ | ||||
|     public static Integer getColumnLength(String columnType) { | ||||
|         if (StringUtils.indexOf(columnType, "(") > 0) { | ||||
|             String length = StringUtils.substringBetween(columnType, "(", ")"); | ||||
|             return Integer.valueOf(length); | ||||
|         } else { | ||||
|             return 0; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,35 @@ | ||||
| package org.dromara.generator.util; | ||||
|  | ||||
| import org.dromara.common.core.constant.Constants; | ||||
| import lombok.AccessLevel; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.apache.velocity.app.Velocity; | ||||
|  | ||||
| import java.util.Properties; | ||||
|  | ||||
| /** | ||||
|  * VelocityEngine工厂 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class VelocityInitializer { | ||||
|  | ||||
|     /** | ||||
|      * 初始化vm方法 | ||||
|      */ | ||||
|     public static void initVelocity() { | ||||
|         Properties p = new Properties(); | ||||
|         try { | ||||
|             // 加载classpath目录下的vm文件 | ||||
|             p.setProperty("resource.loader.file.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader"); | ||||
|             // 定义字符集 | ||||
|             p.setProperty(Velocity.INPUT_ENCODING, Constants.UTF8); | ||||
|             // 初始化Velocity引擎,指定配置Properties | ||||
|             Velocity.init(p); | ||||
|         } catch (Exception e) { | ||||
|             throw new RuntimeException(e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,341 @@ | ||||
| package org.dromara.generator.util; | ||||
|  | ||||
| import cn.hutool.core.collection.CollUtil; | ||||
| import cn.hutool.core.convert.Convert; | ||||
| import cn.hutool.core.lang.Dict; | ||||
| import org.dromara.generator.constant.GenConstants; | ||||
| import org.dromara.common.core.utils.DateUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| import org.dromara.common.json.utils.JsonUtils; | ||||
| import org.dromara.common.mybatis.helper.DataBaseHelper; | ||||
| import org.dromara.generator.domain.GenTable; | ||||
| import org.dromara.generator.domain.GenTableColumn; | ||||
| import lombok.AccessLevel; | ||||
| import lombok.NoArgsConstructor; | ||||
| import org.apache.velocity.VelocityContext; | ||||
|  | ||||
| import java.util.*; | ||||
|  | ||||
| /** | ||||
|  * 模板处理工具类 | ||||
|  * | ||||
|  * @author ruoyi | ||||
|  */ | ||||
| @NoArgsConstructor(access = AccessLevel.PRIVATE) | ||||
| public class VelocityUtils { | ||||
|  | ||||
|     /** | ||||
|      * 项目空间路径 | ||||
|      */ | ||||
|     private static final String PROJECT_PATH = "main/java"; | ||||
|  | ||||
|     /** | ||||
|      * mybatis空间路径 | ||||
|      */ | ||||
|     private static final String MYBATIS_PATH = "main/resources/mapper"; | ||||
|  | ||||
|     /** | ||||
|      * 默认上级菜单,系统工具 | ||||
|      */ | ||||
|     private static final String DEFAULT_PARENT_MENU_ID = "3"; | ||||
|  | ||||
|     /** | ||||
|      * 设置模板变量信息 | ||||
|      * | ||||
|      * @return 模板列表 | ||||
|      */ | ||||
|     public static VelocityContext prepareContext(GenTable genTable) { | ||||
|         String moduleName = genTable.getModuleName(); | ||||
|         String businessName = genTable.getBusinessName(); | ||||
|         String packageName = genTable.getPackageName(); | ||||
|         String tplCategory = genTable.getTplCategory(); | ||||
|         String functionName = genTable.getFunctionName(); | ||||
|  | ||||
|         VelocityContext velocityContext = new VelocityContext(); | ||||
|         velocityContext.put("tplCategory", genTable.getTplCategory()); | ||||
|         velocityContext.put("tableName", genTable.getTableName()); | ||||
|         velocityContext.put("functionName", StringUtils.isNotEmpty(functionName) ? functionName : "【请填写功能名称】"); | ||||
|         velocityContext.put("ClassName", genTable.getClassName()); | ||||
|         velocityContext.put("className", StringUtils.uncapitalize(genTable.getClassName())); | ||||
|         velocityContext.put("moduleName", genTable.getModuleName()); | ||||
|         velocityContext.put("BusinessName", StringUtils.capitalize(genTable.getBusinessName())); | ||||
|         velocityContext.put("businessName", genTable.getBusinessName()); | ||||
|         velocityContext.put("basePackage", getPackagePrefix(packageName)); | ||||
|         velocityContext.put("packageName", packageName); | ||||
|         velocityContext.put("author", genTable.getFunctionAuthor()); | ||||
|         velocityContext.put("datetime", DateUtils.getDate()); | ||||
|         velocityContext.put("pkColumn", genTable.getPkColumn()); | ||||
|         velocityContext.put("importList", getImportList(genTable)); | ||||
|         velocityContext.put("permissionPrefix", getPermissionPrefix(moduleName, businessName)); | ||||
|         velocityContext.put("columns", genTable.getColumns()); | ||||
|         velocityContext.put("table", genTable); | ||||
|         velocityContext.put("dicts", getDicts(genTable)); | ||||
|         setMenuVelocityContext(velocityContext, genTable); | ||||
|         if (GenConstants.TPL_TREE.equals(tplCategory)) { | ||||
|             setTreeVelocityContext(velocityContext, genTable); | ||||
|         } | ||||
|         return velocityContext; | ||||
|     } | ||||
|  | ||||
|     public static void setMenuVelocityContext(VelocityContext context, GenTable genTable) { | ||||
|         String options = genTable.getOptions(); | ||||
|         Dict paramsObj = JsonUtils.parseMap(options); | ||||
|         String parentMenuId = getParentMenuId(paramsObj); | ||||
|         context.put("parentMenuId", parentMenuId); | ||||
|     } | ||||
|  | ||||
|     public static void setTreeVelocityContext(VelocityContext context, GenTable genTable) { | ||||
|         String options = genTable.getOptions(); | ||||
|         Dict paramsObj = JsonUtils.parseMap(options); | ||||
|         String treeCode = getTreecode(paramsObj); | ||||
|         String treeParentCode = getTreeParentCode(paramsObj); | ||||
|         String treeName = getTreeName(paramsObj); | ||||
|  | ||||
|         context.put("treeCode", treeCode); | ||||
|         context.put("treeParentCode", treeParentCode); | ||||
|         context.put("treeName", treeName); | ||||
|         context.put("expandColumn", getExpandColumn(genTable)); | ||||
|         if (paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { | ||||
|             context.put("tree_parent_code", paramsObj.get(GenConstants.TREE_PARENT_CODE)); | ||||
|         } | ||||
|         if (paramsObj.containsKey(GenConstants.TREE_NAME)) { | ||||
|             context.put("tree_name", paramsObj.get(GenConstants.TREE_NAME)); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取模板信息 | ||||
|      * | ||||
|      * @return 模板列表 | ||||
|      */ | ||||
|     public static List<String> getTemplateList(String tplCategory) { | ||||
|         List<String> templates = new ArrayList<>(); | ||||
|         templates.add("vm/java/domain.java.vm"); | ||||
|         templates.add("vm/java/vo.java.vm"); | ||||
|         templates.add("vm/java/bo.java.vm"); | ||||
|         templates.add("vm/java/mapper.java.vm"); | ||||
|         templates.add("vm/java/service.java.vm"); | ||||
|         templates.add("vm/java/serviceImpl.java.vm"); | ||||
|         templates.add("vm/java/controller.java.vm"); | ||||
|         templates.add("vm/xml/mapper.xml.vm"); | ||||
|         if (DataBaseHelper.isOracle()) { | ||||
|             templates.add("vm/sql/oracle/sql.vm"); | ||||
|         } else if (DataBaseHelper.isPostgerSql()) { | ||||
|             templates.add("vm/sql/postgres/sql.vm"); | ||||
|         } else if (DataBaseHelper.isSqlServer()) { | ||||
|             templates.add("vm/sql/sqlserver/sql.vm"); | ||||
|         } else { | ||||
|             templates.add("vm/sql/sql.vm"); | ||||
|         } | ||||
|         templates.add("vm/ts/api.ts.vm"); | ||||
|         templates.add("vm/ts/types.ts.vm"); | ||||
|         if (GenConstants.TPL_CRUD.equals(tplCategory)) { | ||||
|             templates.add("vm/vue/index.vue.vm"); | ||||
|         } else if (GenConstants.TPL_TREE.equals(tplCategory)) { | ||||
|             templates.add("vm/vue/index-tree.vue.vm"); | ||||
|         } | ||||
|         return templates; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取文件名 | ||||
|      */ | ||||
|     public static String getFileName(String template, GenTable genTable) { | ||||
|         // 文件名称 | ||||
|         String fileName = ""; | ||||
|         // 包路径 | ||||
|         String packageName = genTable.getPackageName(); | ||||
|         // 模块名 | ||||
|         String moduleName = genTable.getModuleName(); | ||||
|         // 大写类名 | ||||
|         String className = genTable.getClassName(); | ||||
|         // 业务名称 | ||||
|         String businessName = genTable.getBusinessName(); | ||||
|  | ||||
|         String javaPath = PROJECT_PATH + "/" + StringUtils.replace(packageName, ".", "/"); | ||||
|         String mybatisPath = MYBATIS_PATH + "/" + moduleName; | ||||
|         String vuePath = "vue"; | ||||
|  | ||||
|         if (template.contains("domain.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/domain/{}.java", javaPath, className); | ||||
|         } | ||||
|         if (template.contains("vo.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/domain/vo/{}Vo.java", javaPath, className); | ||||
|         } | ||||
|         if (template.contains("bo.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/domain/bo/{}Bo.java", javaPath, className); | ||||
|         } | ||||
|         if (template.contains("mapper.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/mapper/{}Mapper.java", javaPath, className); | ||||
|         } else if (template.contains("service.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/service/I{}Service.java", javaPath, className); | ||||
|         } else if (template.contains("serviceImpl.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/service/impl/{}ServiceImpl.java", javaPath, className); | ||||
|         } else if (template.contains("controller.java.vm")) { | ||||
|             fileName = StringUtils.format("{}/controller/{}Controller.java", javaPath, className); | ||||
|         } else if (template.contains("mapper.xml.vm")) { | ||||
|             fileName = StringUtils.format("{}/{}Mapper.xml", mybatisPath, className); | ||||
|         } else if (template.contains("sql.vm")) { | ||||
|             fileName = businessName + "Menu.sql"; | ||||
|         } else if (template.contains("api.ts.vm")) { | ||||
|             fileName = StringUtils.format("{}/api/{}/{}/index.ts", vuePath, moduleName, businessName); | ||||
|         } else if (template.contains("types.ts.vm")) { | ||||
|             fileName = StringUtils.format("{}/api/{}/{}/types.ts", vuePath, moduleName, businessName); | ||||
|         } else if (template.contains("index.vue.vm")) { | ||||
|             fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); | ||||
|         } else if (template.contains("index-tree.vue.vm")) { | ||||
|             fileName = StringUtils.format("{}/views/{}/{}/index.vue", vuePath, moduleName, businessName); | ||||
|         } | ||||
|         return fileName; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取包前缀 | ||||
|      * | ||||
|      * @param packageName 包名称 | ||||
|      * @return 包前缀名称 | ||||
|      */ | ||||
|     public static String getPackagePrefix(String packageName) { | ||||
|         int lastIndex = packageName.lastIndexOf("."); | ||||
|         return StringUtils.substring(packageName, 0, lastIndex); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据列类型获取导入包 | ||||
|      * | ||||
|      * @param genTable 业务表对象 | ||||
|      * @return 返回需要导入的包列表 | ||||
|      */ | ||||
|     public static HashSet<String> getImportList(GenTable genTable) { | ||||
|         List<GenTableColumn> columns = genTable.getColumns(); | ||||
|         HashSet<String> importList = new HashSet<>(); | ||||
|         for (GenTableColumn column : columns) { | ||||
|             if (!column.isSuperColumn() && GenConstants.TYPE_DATE.equals(column.getJavaType())) { | ||||
|                 importList.add("java.util.Date"); | ||||
|                 importList.add("com.fasterxml.jackson.annotation.JsonFormat"); | ||||
|             } else if (!column.isSuperColumn() && GenConstants.TYPE_BIGDECIMAL.equals(column.getJavaType())) { | ||||
|                 importList.add("java.math.BigDecimal"); | ||||
|             } else if (!column.isSuperColumn() && "imageUpload".equals(column.getHtmlType())) { | ||||
|                 importList.add("org.dromara.common.translation.annotation.Translation"); | ||||
|                 importList.add("org.dromara.common.translation.constant.TransConstant"); | ||||
|             } | ||||
|         } | ||||
|         return importList; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 根据列类型获取字典组 | ||||
|      * | ||||
|      * @param genTable 业务表对象 | ||||
|      * @return 返回字典组 | ||||
|      */ | ||||
|     public static String getDicts(GenTable genTable) { | ||||
|         List<GenTableColumn> columns = genTable.getColumns(); | ||||
|         Set<String> dicts = new HashSet<>(); | ||||
|         addDicts(dicts, columns); | ||||
|         return StringUtils.join(dicts, ", "); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 添加字典列表 | ||||
|      * | ||||
|      * @param dicts 字典列表 | ||||
|      * @param columns 列集合 | ||||
|      */ | ||||
|     public static void addDicts(Set<String> dicts, List<GenTableColumn> columns) { | ||||
|         for (GenTableColumn column : columns) { | ||||
|             if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( | ||||
|                 column.getHtmlType(), | ||||
|                 new String[] { GenConstants.HTML_SELECT, GenConstants.HTML_RADIO, GenConstants.HTML_CHECKBOX })) { | ||||
|                 dicts.add("'" + column.getDictType() + "'"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取权限前缀 | ||||
|      * | ||||
|      * @param moduleName   模块名称 | ||||
|      * @param businessName 业务名称 | ||||
|      * @return 返回权限前缀 | ||||
|      */ | ||||
|     public static String getPermissionPrefix(String moduleName, String businessName) { | ||||
|         return StringUtils.format("{}:{}", moduleName, businessName); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取上级菜单ID字段 | ||||
|      * | ||||
|      * @param paramsObj 生成其他选项 | ||||
|      * @return 上级菜单ID字段 | ||||
|      */ | ||||
|     public static String getParentMenuId(Dict paramsObj) { | ||||
|         if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.PARENT_MENU_ID) | ||||
|             && StringUtils.isNotEmpty(paramsObj.getStr(GenConstants.PARENT_MENU_ID))) { | ||||
|             return paramsObj.getStr(GenConstants.PARENT_MENU_ID); | ||||
|         } | ||||
|         return DEFAULT_PARENT_MENU_ID; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取树编码 | ||||
|      * | ||||
|      * @param paramsObj 生成其他选项 | ||||
|      * @return 树编码 | ||||
|      */ | ||||
|     public static String getTreecode(Map<String, Object> paramsObj) { | ||||
|         if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_CODE)) { | ||||
|             return StringUtils.toCamelCase(Convert.toStr(paramsObj.get(GenConstants.TREE_CODE))); | ||||
|         } | ||||
|         return StringUtils.EMPTY; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取树父编码 | ||||
|      * | ||||
|      * @param paramsObj 生成其他选项 | ||||
|      * @return 树父编码 | ||||
|      */ | ||||
|     public static String getTreeParentCode(Dict paramsObj) { | ||||
|         if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_PARENT_CODE)) { | ||||
|             return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_PARENT_CODE)); | ||||
|         } | ||||
|         return StringUtils.EMPTY; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取树名称 | ||||
|      * | ||||
|      * @param paramsObj 生成其他选项 | ||||
|      * @return 树名称 | ||||
|      */ | ||||
|     public static String getTreeName(Dict paramsObj) { | ||||
|         if (CollUtil.isNotEmpty(paramsObj) && paramsObj.containsKey(GenConstants.TREE_NAME)) { | ||||
|             return StringUtils.toCamelCase(paramsObj.getStr(GenConstants.TREE_NAME)); | ||||
|         } | ||||
|         return StringUtils.EMPTY; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取需要在哪一列上面显示展开按钮 | ||||
|      * | ||||
|      * @param genTable 业务表对象 | ||||
|      * @return 展开按钮列序号 | ||||
|      */ | ||||
|     public static int getExpandColumn(GenTable genTable) { | ||||
|         String options = genTable.getOptions(); | ||||
|         Dict paramsObj = JsonUtils.parseMap(options); | ||||
|         String treeName = paramsObj.getStr(GenConstants.TREE_NAME); | ||||
|         int num = 0; | ||||
|         for (GenTableColumn column : genTable.getColumns()) { | ||||
|             if (column.isList()) { | ||||
|                 num++; | ||||
|                 String columnName = column.getColumnName(); | ||||
|                 if (columnName.equals(treeName)) { | ||||
|                     break; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|         return num; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,10 @@ | ||||
| # 代码生成 | ||||
| gen: | ||||
|   # 作者 | ||||
|   author: Lion Li | ||||
|   # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool | ||||
|   packageName: org.dromara.system | ||||
|   # 自动去除表前缀,默认是false | ||||
|   autoRemovePre: false | ||||
|   # 表前缀(生成类名不会包含表前缀,多个用逗号分隔) | ||||
|   tablePrefix: sys_ | ||||
| @ -0,0 +1,10 @@ | ||||
| <?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="org.dromara.generator.mapper.GenTableColumnMapper"> | ||||
|  | ||||
|     <resultMap type="org.dromara.generator.domain.GenTableColumn" id="GenTableColumnResult"> | ||||
|     </resultMap> | ||||
|  | ||||
| </mapper> | ||||
| @ -0,0 +1,42 @@ | ||||
| <?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="org.dromara.generator.mapper.GenTableMapper"> | ||||
|  | ||||
|     <!-- 多结构嵌套自动映射需带上每个实体的主键id 否则映射会失败 --> | ||||
|     <resultMap type="org.dromara.generator.domain.GenTable" id="GenTableResult"> | ||||
|         <id property="tableId" column="table_id" /> | ||||
|         <collection property="columns" javaType="java.util.List" resultMap="GenTableColumnResult" /> | ||||
|     </resultMap> | ||||
|  | ||||
|     <resultMap type="org.dromara.generator.domain.GenTableColumn" id="GenTableColumnResult"> | ||||
|         <id property="columnId" column="column_id"/> | ||||
|     </resultMap> | ||||
|  | ||||
|     <sql id="genSelect"> | ||||
|         SELECT t.table_id, t.data_name, t.table_name, t.table_comment, t.sub_table_name, t.sub_table_fk_name, t.class_name, t.tpl_category, t.package_name, t.module_name, t.business_name, t.function_name, t.function_author, t.gen_type, t.gen_path, t.options, t.remark, | ||||
|                c.column_id, c.column_name, c.column_comment, c.column_type, c.java_type, c.java_field, c.is_pk, c.is_increment, c.is_required, c.is_insert, c.is_edit, c.is_list, c.is_query, c.query_type, c.html_type, c.dict_type, c.sort | ||||
|         FROM gen_table t | ||||
|                  LEFT JOIN gen_table_column c ON t.table_id = c.table_id | ||||
|     </sql> | ||||
|  | ||||
|     <select id="selectGenTableById" parameterType="Long" resultMap="GenTableResult"> | ||||
|         <include refid="genSelect"/> | ||||
|         where t.table_id = #{tableId} order by c.sort | ||||
|     </select> | ||||
|  | ||||
|     <select id="selectGenTableByName" parameterType="String" resultMap="GenTableResult"> | ||||
|         <include refid="genSelect"/> | ||||
|         where t.table_name = #{tableName} order by c.sort | ||||
|     </select> | ||||
|  | ||||
|     <select id="selectGenTableAll" parameterType="String" resultMap="GenTableResult"> | ||||
|         <include refid="genSelect"/> | ||||
|         order by c.sort | ||||
|     </select> | ||||
|  | ||||
|     <select id="selectTableNameList" resultType="java.lang.String"> | ||||
|         select table_name from gen_table where data_name = #{dataName,jdbcType=VARCHAR} | ||||
|     </select> | ||||
| </mapper> | ||||
| @ -0,0 +1,3 @@ | ||||
| java包使用 `.` 分割 resource 目录使用 `/` 分割 | ||||
| <br> | ||||
| 此文件目的 防止文件夹粘连找不到 `xml` 文件 | ||||
| @ -0,0 +1,50 @@ | ||||
| package ${packageName}.domain.bo; | ||||
|  | ||||
| import ${packageName}.domain.${ClassName}; | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| import jakarta.validation.constraints.*; | ||||
| #foreach ($import in $importList) | ||||
| import ${import}; | ||||
| #end | ||||
|  | ||||
| /** | ||||
|  * ${functionName}业务对象 ${tableName} | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @AutoMapper(target = ${ClassName}.class, reverseConvertGenerate = false) | ||||
| public class ${ClassName}Bo extends BaseEntity { | ||||
|  | ||||
| #foreach ($column in $columns) | ||||
| #if(!$table.isSuperColumn($column.javaField) && ($column.query || $column.insert || $column.edit)) | ||||
|     /** | ||||
|      * $column.columnComment | ||||
|      */ | ||||
| #if($column.insert && $column.edit) | ||||
| #set($Group="AddGroup.class, EditGroup.class") | ||||
| #elseif($column.insert) | ||||
| #set($Group="AddGroup.class") | ||||
| #elseif($column.edit) | ||||
| #set($Group="EditGroup.class") | ||||
| #end | ||||
| #if($column.required) | ||||
| #if($column.javaType == 'String') | ||||
|     @NotBlank(message = "$column.columnComment不能为空", groups = { $Group }) | ||||
| #else | ||||
|     @NotNull(message = "$column.columnComment不能为空", groups = { $Group }) | ||||
| #end | ||||
| #end | ||||
|     private $column.javaType $column.javaField; | ||||
|  | ||||
| #end | ||||
| #end | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,115 @@ | ||||
| package ${packageName}.controller; | ||||
|  | ||||
| import java.util.List; | ||||
|  | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import jakarta.servlet.http.HttpServletResponse; | ||||
| import jakarta.validation.constraints.*; | ||||
| import cn.dev33.satoken.annotation.SaCheckPermission; | ||||
| import org.springframework.web.bind.annotation.*; | ||||
| import org.springframework.validation.annotation.Validated; | ||||
| import org.dromara.common.idempotent.annotation.RepeatSubmit; | ||||
| import org.dromara.common.log.annotation.Log; | ||||
| import org.dromara.common.web.core.BaseController; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import org.dromara.common.core.domain.R; | ||||
| import org.dromara.common.core.validate.AddGroup; | ||||
| import org.dromara.common.core.validate.EditGroup; | ||||
| import org.dromara.common.log.enums.BusinessType; | ||||
| import org.dromara.common.excel.utils.ExcelUtil; | ||||
| import ${packageName}.domain.vo.${ClassName}Vo; | ||||
| import ${packageName}.domain.bo.${ClassName}Bo; | ||||
| import ${packageName}.service.I${ClassName}Service; | ||||
| #if($table.crud) | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| #elseif($table.tree) | ||||
| #end | ||||
|  | ||||
| /** | ||||
|  * ${functionName} | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| @Validated | ||||
| @RequiredArgsConstructor | ||||
| @RestController | ||||
| @RequestMapping("/${moduleName}/${businessName}") | ||||
| public class ${ClassName}Controller extends BaseController { | ||||
|  | ||||
|     private final I${ClassName}Service ${className}Service; | ||||
|  | ||||
|     /** | ||||
|      * 查询${functionName}列表 | ||||
|      */ | ||||
|     @SaCheckPermission("${permissionPrefix}:list") | ||||
|     @GetMapping("/list") | ||||
| #if($table.crud) | ||||
|     public TableDataInfo<${ClassName}Vo> list(${ClassName}Bo bo, PageQuery pageQuery) { | ||||
|         return ${className}Service.queryPageList(bo, pageQuery); | ||||
|     } | ||||
| #elseif($table.tree) | ||||
|     public R<List<${ClassName}Vo>> list(${ClassName}Bo bo) { | ||||
|         List<${ClassName}Vo> list = ${className}Service.queryList(bo); | ||||
|         return R.ok(list); | ||||
|     } | ||||
| #end | ||||
|  | ||||
|     /** | ||||
|      * 导出${functionName}列表 | ||||
|      */ | ||||
|     @SaCheckPermission("${permissionPrefix}:export") | ||||
|     @Log(title = "${functionName}", businessType = BusinessType.EXPORT) | ||||
|     @PostMapping("/export") | ||||
|     public void export(${ClassName}Bo bo, HttpServletResponse response) { | ||||
|         List<${ClassName}Vo> list = ${className}Service.queryList(bo); | ||||
|         ExcelUtil.exportExcel(list, "${functionName}", ${ClassName}Vo.class, response); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 获取${functionName}详细信息 | ||||
|      * | ||||
|      * @param ${pkColumn.javaField} 主键 | ||||
|      */ | ||||
|     @SaCheckPermission("${permissionPrefix}:query") | ||||
|     @GetMapping("/{${pkColumn.javaField}}") | ||||
|     public R<${ClassName}Vo> getInfo(@NotNull(message = "主键不能为空") | ||||
|                                      @PathVariable ${pkColumn.javaType} ${pkColumn.javaField}) { | ||||
|         return R.ok(${className}Service.queryById(${pkColumn.javaField})); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增${functionName} | ||||
|      */ | ||||
|     @SaCheckPermission("${permissionPrefix}:add") | ||||
|     @Log(title = "${functionName}", businessType = BusinessType.INSERT) | ||||
|     @RepeatSubmit() | ||||
|     @PostMapping() | ||||
|     public R<Void> add(@Validated(AddGroup.class) @RequestBody ${ClassName}Bo bo) { | ||||
|         return toAjax(${className}Service.insertByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改${functionName} | ||||
|      */ | ||||
|     @SaCheckPermission("${permissionPrefix}:edit") | ||||
|     @Log(title = "${functionName}", businessType = BusinessType.UPDATE) | ||||
|     @RepeatSubmit() | ||||
|     @PutMapping() | ||||
|     public R<Void> edit(@Validated(EditGroup.class) @RequestBody ${ClassName}Bo bo) { | ||||
|         return toAjax(${className}Service.updateByBo(bo)); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 删除${functionName} | ||||
|      * | ||||
|      * @param ${pkColumn.javaField}s 主键串 | ||||
|      */ | ||||
|     @SaCheckPermission("${permissionPrefix}:remove") | ||||
|     @Log(title = "${functionName}", businessType = BusinessType.DELETE) | ||||
|     @DeleteMapping("/{${pkColumn.javaField}s}") | ||||
|     public R<Void> remove(@NotEmpty(message = "主键不能为空") | ||||
|                           @PathVariable ${pkColumn.javaType}[] ${pkColumn.javaField}s) { | ||||
|         return toAjax(${className}Service.deleteWithValidByIds(List.of(${pkColumn.javaField}s), true)); | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,60 @@ | ||||
| package ${packageName}.domain; | ||||
|  | ||||
| #foreach ($column in $columns) | ||||
| #if($column.javaField=='tenantId') | ||||
| #set($IsTenant=1) | ||||
| #end | ||||
| #end | ||||
| #if($IsTenant==1) | ||||
| import org.dromara.common.tenant.core.TenantEntity; | ||||
| #else | ||||
| import org.dromara.common.mybatis.core.domain.BaseEntity; | ||||
| #end | ||||
| import com.baomidou.mybatisplus.annotation.*; | ||||
| import lombok.Data; | ||||
| import lombok.EqualsAndHashCode; | ||||
| #foreach ($import in $importList) | ||||
| import ${import}; | ||||
| #end | ||||
|  | ||||
| import java.io.Serial; | ||||
|  | ||||
| /** | ||||
|  * ${functionName}对象 ${tableName} | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| #if($IsTenant==1) | ||||
| #set($Entity="TenantEntity") | ||||
| #else | ||||
| #set($Entity="BaseEntity") | ||||
| #end | ||||
| @Data | ||||
| @EqualsAndHashCode(callSuper = true) | ||||
| @TableName("${tableName}") | ||||
| public class ${ClassName} extends ${Entity} { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
| #foreach ($column in $columns) | ||||
| #if(!$table.isSuperColumn($column.javaField)) | ||||
|     /** | ||||
|      * $column.columnComment | ||||
|      */ | ||||
| #if($column.javaField=='delFlag') | ||||
|     @TableLogic | ||||
| #end | ||||
| #if($column.javaField=='version') | ||||
|     @Version | ||||
| #end | ||||
| #if($column.isPk==1) | ||||
|     @TableId(value = "$column.columnName") | ||||
| #end | ||||
|     private $column.javaType $column.javaField; | ||||
|  | ||||
| #end | ||||
| #end | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,15 @@ | ||||
| package ${packageName}.mapper; | ||||
|  | ||||
| import ${packageName}.domain.${ClassName}; | ||||
| import ${packageName}.domain.vo.${ClassName}Vo; | ||||
| import org.dromara.common.mybatis.core.mapper.BaseMapperPlus; | ||||
|  | ||||
| /** | ||||
|  * ${functionName}Mapper接口 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| public interface ${ClassName}Mapper extends BaseMapperPlus<${ClassName}, ${ClassName}Vo> { | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,72 @@ | ||||
| package ${packageName}.service; | ||||
|  | ||||
| import ${packageName}.domain.vo.${ClassName}Vo; | ||||
| import ${packageName}.domain.bo.${ClassName}Bo; | ||||
| #if($table.crud) | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| #end | ||||
|  | ||||
| import java.util.Collection; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * ${functionName}Service接口 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| public interface I${ClassName}Service { | ||||
|  | ||||
|     /** | ||||
|      * 查询${functionName} | ||||
|      * | ||||
|      * @param ${pkColumn.javaField} 主键 | ||||
|      * @return ${functionName} | ||||
|      */ | ||||
|     ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}); | ||||
|  | ||||
| #if($table.crud) | ||||
|     /** | ||||
|      * 分页查询${functionName}列表 | ||||
|      * | ||||
|      * @param bo        查询条件 | ||||
|      * @param pageQuery 分页参数 | ||||
|      * @return ${functionName}分页列表 | ||||
|      */ | ||||
|     TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery); | ||||
| #end | ||||
|  | ||||
|     /** | ||||
|      * 查询符合条件的${functionName}列表 | ||||
|      * | ||||
|      * @param bo 查询条件 | ||||
|      * @return ${functionName}列表 | ||||
|      */ | ||||
|     List<${ClassName}Vo> queryList(${ClassName}Bo bo); | ||||
|  | ||||
|     /** | ||||
|      * 新增${functionName} | ||||
|      * | ||||
|      * @param bo ${functionName} | ||||
|      * @return 是否新增成功 | ||||
|      */ | ||||
|     Boolean insertByBo(${ClassName}Bo bo); | ||||
|  | ||||
|     /** | ||||
|      * 修改${functionName} | ||||
|      * | ||||
|      * @param bo ${functionName} | ||||
|      * @return 是否修改成功 | ||||
|      */ | ||||
|     Boolean updateByBo(${ClassName}Bo bo); | ||||
|  | ||||
|     /** | ||||
|      * 校验并批量删除${functionName}信息 | ||||
|      * | ||||
|      * @param ids     待删除的主键集合 | ||||
|      * @param isValid 是否进行有效性校验 | ||||
|      * @return 是否删除成功 | ||||
|      */ | ||||
|     Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid); | ||||
| } | ||||
| @ -0,0 +1,158 @@ | ||||
| package ${packageName}.service.impl; | ||||
|  | ||||
| import org.dromara.common.core.utils.MapstructUtils; | ||||
| import org.dromara.common.core.utils.StringUtils; | ||||
| #if($table.crud) | ||||
| import org.dromara.common.mybatis.core.page.TableDataInfo; | ||||
| import org.dromara.common.mybatis.core.page.PageQuery; | ||||
| import com.baomidou.mybatisplus.extension.plugins.pagination.Page; | ||||
| #end | ||||
| import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; | ||||
| import com.baomidou.mybatisplus.core.toolkit.Wrappers; | ||||
| import lombok.RequiredArgsConstructor; | ||||
| import org.springframework.stereotype.Service; | ||||
| import ${packageName}.domain.bo.${ClassName}Bo; | ||||
| import ${packageName}.domain.vo.${ClassName}Vo; | ||||
| import ${packageName}.domain.${ClassName}; | ||||
| import ${packageName}.mapper.${ClassName}Mapper; | ||||
| import ${packageName}.service.I${ClassName}Service; | ||||
|  | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| import java.util.Collection; | ||||
|  | ||||
| /** | ||||
|  * ${functionName}Service业务层处理 | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| @RequiredArgsConstructor | ||||
| @Service | ||||
| public class ${ClassName}ServiceImpl implements I${ClassName}Service { | ||||
|  | ||||
|     private final ${ClassName}Mapper baseMapper; | ||||
|  | ||||
|     /** | ||||
|      * 查询${functionName} | ||||
|      * | ||||
|      * @param ${pkColumn.javaField} 主键 | ||||
|      * @return ${functionName} | ||||
|      */ | ||||
|     @Override | ||||
|     public ${ClassName}Vo queryById(${pkColumn.javaType} ${pkColumn.javaField}){ | ||||
|         return baseMapper.selectVoById(${pkColumn.javaField}); | ||||
|     } | ||||
|  | ||||
| #if($table.crud) | ||||
|     /** | ||||
|      * 分页查询${functionName}列表 | ||||
|      * | ||||
|      * @param bo        查询条件 | ||||
|      * @param pageQuery 分页参数 | ||||
|      * @return ${functionName}分页列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public TableDataInfo<${ClassName}Vo> queryPageList(${ClassName}Bo bo, PageQuery pageQuery) { | ||||
|         LambdaQueryWrapper<${ClassName}> lqw = buildQueryWrapper(bo); | ||||
|         Page<${ClassName}Vo> result = baseMapper.selectVoPage(pageQuery.build(), lqw); | ||||
|         return TableDataInfo.build(result); | ||||
|     } | ||||
| #end | ||||
|  | ||||
|     /** | ||||
|      * 查询符合条件的${functionName}列表 | ||||
|      * | ||||
|      * @param bo 查询条件 | ||||
|      * @return ${functionName}列表 | ||||
|      */ | ||||
|     @Override | ||||
|     public List<${ClassName}Vo> queryList(${ClassName}Bo bo) { | ||||
|         LambdaQueryWrapper<${ClassName}> lqw = buildQueryWrapper(bo); | ||||
|         return baseMapper.selectVoList(lqw); | ||||
|     } | ||||
|  | ||||
|     private LambdaQueryWrapper<${ClassName}> buildQueryWrapper(${ClassName}Bo bo) { | ||||
|         Map<String, Object> params = bo.getParams(); | ||||
|         LambdaQueryWrapper<${ClassName}> lqw = Wrappers.lambdaQuery(); | ||||
| #foreach($column in $columns) | ||||
| #if($column.query) | ||||
| #set($queryType=$column.queryType) | ||||
| #set($javaField=$column.javaField) | ||||
| #set($javaType=$column.javaType) | ||||
| #set($columnName=$column.columnName) | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
| #set($mpMethod=$column.queryType.toLowerCase()) | ||||
| #if($queryType != 'BETWEEN') | ||||
| #if($javaType == 'String') | ||||
| #set($condition='StringUtils.isNotBlank(bo.get'+$AttrName+'())') | ||||
| #else | ||||
| #set($condition='bo.get'+$AttrName+'() != null') | ||||
| #end | ||||
|         lqw.$mpMethod($condition, ${ClassName}::get$AttrName, bo.get$AttrName()); | ||||
| #else | ||||
|         lqw.between(params.get("begin$AttrName") != null && params.get("end$AttrName") != null, | ||||
|             ${ClassName}::get$AttrName ,params.get("begin$AttrName"), params.get("end$AttrName")); | ||||
| #end | ||||
| #end | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
| #if($column.isPk==1) | ||||
|         lqw.orderByAsc(${ClassName}::get$AttrName); | ||||
| #end | ||||
| #end | ||||
|         return lqw; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 新增${functionName} | ||||
|      * | ||||
|      * @param bo ${functionName} | ||||
|      * @return 是否新增成功 | ||||
|      */ | ||||
|     @Override | ||||
|     public Boolean insertByBo(${ClassName}Bo bo) { | ||||
|         ${ClassName} add = MapstructUtils.convert(bo, ${ClassName}.class); | ||||
|         validEntityBeforeSave(add); | ||||
|         boolean flag = baseMapper.insert(add) > 0; | ||||
| #set($pk=$pkColumn.javaField.substring(0,1).toUpperCase() + ${pkColumn.javaField.substring(1)}) | ||||
|         if (flag) { | ||||
|             bo.set$pk(add.get$pk()); | ||||
|         } | ||||
|         return flag; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 修改${functionName} | ||||
|      * | ||||
|      * @param bo ${functionName} | ||||
|      * @return 是否修改成功 | ||||
|      */ | ||||
|     @Override | ||||
|     public Boolean updateByBo(${ClassName}Bo bo) { | ||||
|         ${ClassName} update = MapstructUtils.convert(bo, ${ClassName}.class); | ||||
|         validEntityBeforeSave(update); | ||||
|         return baseMapper.updateById(update) > 0; | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 保存前的数据校验 | ||||
|      */ | ||||
|     private void validEntityBeforeSave(${ClassName} entity){ | ||||
|         //TODO 做一些数据校验,如唯一约束 | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * 校验并批量删除${functionName}信息 | ||||
|      * | ||||
|      * @param ids     待删除的主键集合 | ||||
|      * @param isValid 是否进行有效性校验 | ||||
|      * @return 是否删除成功 | ||||
|      */ | ||||
|     @Override | ||||
|     public Boolean deleteWithValidByIds(Collection<${pkColumn.javaType}> ids, Boolean isValid) { | ||||
|         if(isValid){ | ||||
|             //TODO 做一些业务上的校验,判断是否需要校验 | ||||
|         } | ||||
|         return baseMapper.deleteByIds(ids) > 0; | ||||
|     } | ||||
| } | ||||
| @ -0,0 +1,66 @@ | ||||
| package ${packageName}.domain.vo; | ||||
|  | ||||
| #foreach ($import in $importList) | ||||
| import ${import}; | ||||
| #end | ||||
| import ${packageName}.domain.${ClassName}; | ||||
| import com.alibaba.excel.annotation.ExcelIgnoreUnannotated; | ||||
| import com.alibaba.excel.annotation.ExcelProperty; | ||||
| import org.dromara.common.excel.annotation.ExcelDictFormat; | ||||
| import org.dromara.common.excel.convert.ExcelDictConvert; | ||||
| import io.github.linpeilie.annotations.AutoMapper; | ||||
| import lombok.Data; | ||||
|  | ||||
| import java.io.Serial; | ||||
| import java.io.Serializable; | ||||
| import java.util.Date; | ||||
|  | ||||
|  | ||||
|  | ||||
| /** | ||||
|  * ${functionName}视图对象 ${tableName} | ||||
|  * | ||||
|  * @author ${author} | ||||
|  * @date ${datetime} | ||||
|  */ | ||||
| @Data | ||||
| @ExcelIgnoreUnannotated | ||||
| @AutoMapper(target = ${ClassName}.class) | ||||
| public class ${ClassName}Vo implements Serializable { | ||||
|  | ||||
|     @Serial | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
| #foreach ($column in $columns) | ||||
| #if($column.list) | ||||
|     /** | ||||
|      * $column.columnComment | ||||
|      */ | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #if(${column.dictType} && ${column.dictType} != '') | ||||
|     @ExcelProperty(value = "${comment}", converter = ExcelDictConvert.class) | ||||
|     @ExcelDictFormat(dictType = "${column.dictType}") | ||||
| #elseif($parentheseIndex != -1) | ||||
|     @ExcelProperty(value = "${comment}", converter = ExcelDictConvert.class) | ||||
|     @ExcelDictFormat(readConverterExp = "$column.readConverterExp()") | ||||
| #else | ||||
|     @ExcelProperty(value = "${comment}") | ||||
| #end | ||||
|     private $column.javaType $column.javaField; | ||||
|  | ||||
| #if($column.htmlType == "imageUpload") | ||||
|     /** | ||||
|      * ${column.columnComment}Url | ||||
|      */ | ||||
|     @Translation(type = TransConstant.OSS_ID_TO_URL, mapper = "${column.javaField}") | ||||
|     private String ${column.javaField}Url; | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|  | ||||
| } | ||||
| @ -0,0 +1,19 @@ | ||||
| -- 菜单 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[0]}, '${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 103, 1, sysdate, null, null, '${functionName}菜单'); | ||||
|  | ||||
| -- 按钮 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[1]}, '${functionName}查询', ${table.menuIds[0]}, '1',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:query',        '#', 103, 1, sysdate, null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[2]}, '${functionName}新增', ${table.menuIds[0]}, '2',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:add',          '#', 103, 1, sysdate, null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[3]}, '${functionName}修改', ${table.menuIds[0]}, '3',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:edit',         '#', 103, 1, sysdate, null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[4]}, '${functionName}删除', ${table.menuIds[0]}, '4',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:remove',       '#', 103, 1, sysdate, null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[5]}, '${functionName}导出', ${table.menuIds[0]}, '5',  '#', '', 1,  0, 'F', '0', '0', '${permissionPrefix}:export',       '#', 103, 1, sysdate, null, null, ''); | ||||
| @ -0,0 +1,20 @@ | ||||
| -- 菜单 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[0]}, '${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 103, 1, now(), null, null, '${functionName}菜单'); | ||||
|  | ||||
| -- 按钮 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[1]}, '${functionName}查询', ${table.menuIds[0]}, '1',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query',        '#', 103, 1, now(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[2]}, '${functionName}新增', ${table.menuIds[0]}, '2',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add',          '#', 103, 1, now(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[3]}, '${functionName}修改', ${table.menuIds[0]}, '3',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit',         '#', 103, 1, now(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[4]}, '${functionName}删除', ${table.menuIds[0]}, '4',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove',       '#', 103, 1, now(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[5]}, '${functionName}导出', ${table.menuIds[0]}, '5',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export',       '#', 103, 1, now(), null, null, ''); | ||||
|  | ||||
| @ -0,0 +1,19 @@ | ||||
| -- 菜单 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[0]}, '${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 103, 1, sysdate(), null, null, '${functionName}菜单'); | ||||
|  | ||||
| -- 按钮 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[1]}, '${functionName}查询', ${table.menuIds[0]}, '1',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query',        '#', 103, 1, sysdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[2]}, '${functionName}新增', ${table.menuIds[0]}, '2',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add',          '#', 103, 1, sysdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[3]}, '${functionName}修改', ${table.menuIds[0]}, '3',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit',         '#', 103, 1, sysdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[4]}, '${functionName}删除', ${table.menuIds[0]}, '4',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove',       '#', 103, 1, sysdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[5]}, '${functionName}导出', ${table.menuIds[0]}, '5',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export',       '#', 103, 1, sysdate(), null, null, ''); | ||||
| @ -0,0 +1,19 @@ | ||||
| -- 菜单 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[0]}, '${functionName}', '${parentMenuId}', '1', '${businessName}', '${moduleName}/${businessName}/index', 1, 0, 'C', '0', '0', '${permissionPrefix}:list', '#', 103, 1, getdate(), null, null, '${functionName}菜单'); | ||||
|  | ||||
| -- 按钮 SQL | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[1]}, '${functionName}查询', ${table.menuIds[0]}, '1',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:query',        '#', 103, 1, getdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[2]}, '${functionName}新增', ${table.menuIds[0]}, '2',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:add',          '#', 103, 1, getdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[3]}, '${functionName}修改', ${table.menuIds[0]}, '3',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:edit',         '#', 103, 1, getdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[4]}, '${functionName}删除', ${table.menuIds[0]}, '4',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:remove',       '#', 103, 1, getdate(), null, null, ''); | ||||
|  | ||||
| insert into sys_menu (menu_id, menu_name, parent_id, order_num, path, component, is_frame, is_cache, menu_type, visible, status, perms, icon, create_dept, create_by, create_time, update_by, update_time, remark) | ||||
| values(${table.menuIds[5]}, '${functionName}导出', ${table.menuIds[0]}, '5',  '#', '', 1, 0, 'F', '0', '0', '${permissionPrefix}:export',       '#', 103, 1, getdate(), null, null, ''); | ||||
| @ -0,0 +1,63 @@ | ||||
| import request from '@/utils/request'; | ||||
| import { AxiosPromise } from 'axios'; | ||||
| import { ${BusinessName}VO, ${BusinessName}Form, ${BusinessName}Query } from '@/api/${moduleName}/${businessName}/types'; | ||||
|  | ||||
| /** | ||||
|  * 查询${functionName}列表 | ||||
|  * @param query | ||||
|  * @returns {*} | ||||
|  */ | ||||
|  | ||||
| export const list${BusinessName} = (query?: ${BusinessName}Query): AxiosPromise<${BusinessName}VO[]> => { | ||||
|   return request({ | ||||
|     url: '/${moduleName}/${businessName}/list', | ||||
|     method: 'get', | ||||
|     params: query | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 查询${functionName}详细 | ||||
|  * @param ${pkColumn.javaField} | ||||
|  */ | ||||
| export const get${BusinessName} = (${pkColumn.javaField}: string | number): AxiosPromise<${BusinessName}VO> => { | ||||
|   return request({ | ||||
|     url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, | ||||
|     method: 'get' | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 新增${functionName} | ||||
|  * @param data | ||||
|  */ | ||||
| export const add${BusinessName} = (data: ${BusinessName}Form) => { | ||||
|   return request({ | ||||
|     url: '/${moduleName}/${businessName}', | ||||
|     method: 'post', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 修改${functionName} | ||||
|  * @param data | ||||
|  */ | ||||
| export const update${BusinessName} = (data: ${BusinessName}Form) => { | ||||
|   return request({ | ||||
|     url: '/${moduleName}/${businessName}', | ||||
|     method: 'put', | ||||
|     data: data | ||||
|   }); | ||||
| }; | ||||
|  | ||||
| /** | ||||
|  * 删除${functionName} | ||||
|  * @param ${pkColumn.javaField} | ||||
|  */ | ||||
| export const del${BusinessName} = (${pkColumn.javaField}: string | number | Array<string | number>) => { | ||||
|   return request({ | ||||
|     url: '/${moduleName}/${businessName}/' + ${pkColumn.javaField}, | ||||
|     method: 'delete' | ||||
|   }); | ||||
| }; | ||||
| @ -0,0 +1,64 @@ | ||||
| export interface ${BusinessName}VO { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.list) | ||||
|   /** | ||||
|    * $column.columnComment | ||||
|    */ | ||||
|   $column.javaField:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number; | ||||
|                         #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; | ||||
|                         #elseif($column.javaType == 'Boolean') boolean; | ||||
|                         #else string; | ||||
|                     #end | ||||
| #if($column.htmlType == "imageUpload") | ||||
|   /** | ||||
|    * ${column.columnComment}Url | ||||
|    */ | ||||
|   ${column.javaField}Url: string; | ||||
| #end | ||||
| #end | ||||
| #end | ||||
| #if ($table.tree) | ||||
|     /** | ||||
|      * 子对象 | ||||
|      */ | ||||
|     children: ${BusinessName}VO[]; | ||||
| #end | ||||
| } | ||||
|  | ||||
| export interface ${BusinessName}Form extends BaseEntity { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.insert || $column.edit) | ||||
|   /** | ||||
|    * $column.columnComment | ||||
|    */ | ||||
|   $column.javaField?:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number; | ||||
|                         #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; | ||||
|                         #elseif($column.javaType == 'Boolean') boolean; | ||||
|                         #else string; | ||||
|                     #end | ||||
| #end | ||||
| #end | ||||
| } | ||||
|  | ||||
| export interface ${BusinessName}Query #if(!${treeCode})extends PageQuery #end{ | ||||
|  | ||||
| #foreach ($column in $columns) | ||||
| #if($column.query) | ||||
|   /** | ||||
|    * $column.columnComment | ||||
|    */ | ||||
|   $column.javaField?:#if($column.javaField.indexOf("id") != -1 || $column.javaField.indexOf("Id") != -1) string | number; | ||||
|                         #elseif($column.javaType == 'Long' || $column.javaType == 'Integer' || $column.javaType == 'Double' || $column.javaType == 'Float' || $column.javaType == 'BigDecimal') number; | ||||
|                         #elseif($column.javaType == 'Boolean') boolean; | ||||
|                         #else string; | ||||
|                     #end | ||||
| #end | ||||
| #end | ||||
|     /** | ||||
|      * 日期范围参数 | ||||
|      */ | ||||
|     params?: any; | ||||
| } | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -0,0 +1,498 @@ | ||||
| <template> | ||||
|   <div class="p-2"> | ||||
|     <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> | ||||
|       <div v-show="showSearch" class="mb-[10px]"> | ||||
|         <el-card shadow="hover"> | ||||
|           <el-form ref="queryFormRef" :model="queryParams" :inline="true"> | ||||
| #foreach($column in $columns) | ||||
| #if($column.query) | ||||
| #set($dictType=$column.dictType) | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #if($column.htmlType == "input" || $column.htmlType == "textarea") | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
| #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> | ||||
|                 <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable> | ||||
|                 <el-option label="请选择字典生成" value="" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-date-picker clearable | ||||
|                 v-model="queryParams.${column.javaField}" | ||||
|                 type="date" | ||||
|                 value-format="YYYY-MM-DD" | ||||
|                 placeholder="选择${comment}" | ||||
|               /> | ||||
|             </el-form-item> | ||||
| #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
|             <el-form-item label="${comment}" style="width: 308px"> | ||||
|               <el-date-picker | ||||
|                 v-model="dateRange${AttrName}" | ||||
|                 value-format="YYYY-MM-DD HH:mm:ss" | ||||
|                 type="daterange" | ||||
|                 range-separator="-" | ||||
|                 start-placeholder="开始日期" | ||||
|                 end-placeholder="结束日期" | ||||
|                 :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" | ||||
|               /> | ||||
|             </el-form-item> | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </el-card> | ||||
|       </div> | ||||
|     </transition> | ||||
|  | ||||
|     <el-card shadow="never"> | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd()" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="info" plain icon="Sort" @click="handleToggleExpandAll">展开/折叠</el-button> | ||||
|           </el-col> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
|       </template> | ||||
|       <el-table | ||||
|         ref="${businessName}TableRef" | ||||
|         v-loading="loading" | ||||
|         :data="${businessName}List" | ||||
|         row-key="${treeCode}" | ||||
|         :default-expand-all="isExpandAll" | ||||
|         :tree-props="{ children: 'children', hasChildren: 'hasChildren' }" | ||||
|       > | ||||
| #foreach($column in $columns) | ||||
| #set($javaField=$column.javaField) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #if($column.pk) | ||||
| #elseif($column.list && $column.htmlType == "datetime") | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> | ||||
|           <template #default="scope"> | ||||
|             <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
| #elseif($column.list && $column.htmlType == "imageUpload") | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}Url" width="100"> | ||||
|           <template #default="scope"> | ||||
|             <image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
| #elseif($column.list && $column.dictType && "" != $column.dictType) | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}"> | ||||
|           <template #default="scope"> | ||||
| #if($column.htmlType == "checkbox") | ||||
|             <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/> | ||||
| #else | ||||
|             <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/> | ||||
| #end | ||||
|           </template> | ||||
|         </el-table-column> | ||||
| #elseif($column.list && "" != $javaField) | ||||
| #if(${foreach.index} == 1) | ||||
|         <el-table-column label="${comment}" prop="${javaField}" /> | ||||
| #else | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}" /> | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|         <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|           <template #default="scope"> | ||||
|             <el-tooltip content="修改" placement="top"> | ||||
|               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']" /> | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="新增" placement="top"> | ||||
|               <el-button link type="primary" icon="Plus" @click="handleAdd(scope.row)" v-hasPermi="['${moduleName}:${businessName}:add']" /> | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="删除" placement="top"> | ||||
|               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']" /> | ||||
|             </el-tooltip> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|     </el-card> | ||||
|     <!-- 添加或修改${functionName}对话框 --> | ||||
|     <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> | ||||
|       <el-form ref="${businessName}FormRef" :model="form" :rules="rules" label-width="80px"> | ||||
| #foreach($column in $columns) | ||||
| #set($field=$column.javaField) | ||||
| #if(($column.insert || $column.edit) && !$column.pk) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #set($dictType=$column.dictType) | ||||
| #if("" != $treeParentCode && $column.javaField == $treeParentCode) | ||||
|         <el-form-item label="${comment}" prop="${treeParentCode}"> | ||||
|           <el-tree-select | ||||
|             v-model="form.${treeParentCode}" | ||||
|             :data="${businessName}Options" | ||||
|             :props="{ value: '${treeCode}', label: '${treeName}', children: 'children' }" | ||||
|             value-key="${treeCode}" | ||||
|             placeholder="请选择${comment}" | ||||
|             check-strictly | ||||
|           /> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "input") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-input v-model="form.${field}" placeholder="请输入${comment}" /> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "imageUpload") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <image-upload v-model="form.${field}"/> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "fileUpload") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <file-upload v-model="form.${field}"/> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "editor") | ||||
|         <el-form-item label="${comment}"> | ||||
|           <editor v-model="form.${field}" :min-height="192"/> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "select" && "" != $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-select v-model="form.${field}" placeholder="请选择${comment}"> | ||||
|             <el-option | ||||
|               v-for="dict in ${dictType}" | ||||
|               :key="dict.value" | ||||
|               :label="dict.label" | ||||
| #if($column.javaType == "Integer" || $column.javaType == "Long") | ||||
|               :value="parseInt(dict.value)" | ||||
| #else | ||||
|               :value="dict.value" | ||||
| #end | ||||
|             ></el-option> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "select" && $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-select v-model="form.${field}" placeholder="请选择${comment}"> | ||||
|             <el-option label="请选择字典生成" value="" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "checkbox" && "" != $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-checkbox-group v-model="form.${field}"> | ||||
|             <el-checkbox | ||||
|               v-for="dict in ${dictType}" | ||||
|               :key="dict.value" | ||||
|               :label="dict.value"> | ||||
|               {{dict.label}} | ||||
|             </el-checkbox> | ||||
|           </el-checkbox-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "checkbox" && $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-checkbox-group v-model="form.${field}"> | ||||
|             <el-checkbox>请选择字典生成</el-checkbox> | ||||
|           </el-checkbox-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "radio" && "" != $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-radio-group v-model="form.${field}"> | ||||
|             <el-radio | ||||
|               v-for="dict in ${dictType}" | ||||
|               :key="dict.value" | ||||
| #if($column.javaType == "Integer" || $column.javaType == "Long") | ||||
|               :value="parseInt(dict.value)" | ||||
| #else | ||||
|               :value="dict.value" | ||||
| #end | ||||
|             >{{dict.label}}</el-radio> | ||||
|           </el-radio-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "radio" && $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-radio-group v-model="form.${field}"> | ||||
|             <el-radio value="1">请选择字典生成</el-radio> | ||||
|           </el-radio-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "datetime") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-date-picker clearable | ||||
|             v-model="form.${field}" | ||||
|             type="datetime" | ||||
|             value-format="YYYY-MM-DD HH:mm:ss" | ||||
|             placeholder="选择${comment}" | ||||
|           /> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "textarea") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> | ||||
|         </el-form-item> | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <div class="dialog-footer"> | ||||
|           <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|           <el-button @click="cancel">取 消</el-button> | ||||
|         </div> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup name="${BusinessName}" lang="ts"> | ||||
| import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from "@/api/${moduleName}/${businessName}"; | ||||
| import { ${BusinessName}VO, ${BusinessName}Query, ${BusinessName}Form } from '@/api/${moduleName}/${businessName}/types'; | ||||
|  | ||||
| type ${BusinessName}Option = { | ||||
|   ${treeCode}: number; | ||||
|   ${treeName}: string; | ||||
|   children?: ${BusinessName}Option[]; | ||||
| } | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance;; | ||||
|  | ||||
| #if(${dicts} != '') | ||||
| #set($dictsNoSymbol=$dicts.replace("'", "")) | ||||
| const { ${dictsNoSymbol} } = toRefs<any>(proxy?.useDict(${dicts})); | ||||
| #end | ||||
|  | ||||
| const ${businessName}List = ref<${BusinessName}VO[]>([]); | ||||
| const ${businessName}Options = ref<${BusinessName}Option[]>([]); | ||||
| const buttonLoading = ref(false); | ||||
| const showSearch = ref(true); | ||||
| const isExpandAll = ref(true); | ||||
| const loading = ref(false); | ||||
|  | ||||
| const queryFormRef = ref<ElFormInstance>(); | ||||
| const ${businessName}FormRef = ref<ElFormInstance>(); | ||||
| const ${businessName}TableRef = ref<ElTableInstance>() | ||||
|  | ||||
| const dialog = reactive<DialogOption>({ | ||||
|     visible: false, | ||||
|     title: '' | ||||
| }); | ||||
|  | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
| const dateRange${AttrName} = ref<[DateModelType, DateModelType]>(['', '']); | ||||
| #end | ||||
| #end | ||||
|  | ||||
| const initFormData: ${BusinessName}Form = { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.insert || $column.edit) | ||||
| #if($column.htmlType == "checkbox") | ||||
|     $column.javaField: []#if($foreach.count != $columns.size()),#end | ||||
| #else | ||||
|     $column.javaField: undefined#if($foreach.count != $columns.size()),#end | ||||
| #end | ||||
| #end | ||||
| #end | ||||
| } | ||||
|  | ||||
| const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({ | ||||
|   form: {...initFormData}, | ||||
|   queryParams: { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.query) | ||||
| #if($column.htmlType != "datetime" || $column.queryType != "BETWEEN") | ||||
|     $column.javaField: undefined, | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|     params: { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.query) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
|       $column.javaField: undefined#if($foreach.count != $columns.size()),#end | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|     } | ||||
|   }, | ||||
|   rules: { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.insert || $column.edit) | ||||
| #if($column.required) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
|     $column.javaField: [ | ||||
|       { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } | ||||
|     ]#if($foreach.count != $columns.size()),#end | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|   } | ||||
| }); | ||||
|  | ||||
| const { queryParams, form, rules } = toRefs(data); | ||||
|  | ||||
| /** 查询${functionName}列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true; | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
|   queryParams.value.params = {}; | ||||
| #break | ||||
| #end | ||||
| #end | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
|   proxy?.addDateRange(queryParams.value, dateRange${AttrName}.value, '${AttrName}'); | ||||
| #end | ||||
| #end | ||||
|   const res = await list${BusinessName}(queryParams.value); | ||||
|   const data = proxy?.handleTree<${BusinessName}VO>(res.data, "${treeCode}", "${treeParentCode}"); | ||||
|   if (data) { | ||||
|     ${businessName}List.value = data; | ||||
|     loading.value = false; | ||||
|   } | ||||
| } | ||||
|  | ||||
| /** 查询${functionName}下拉树结构 */ | ||||
| const getTreeselect = async () => { | ||||
|   const res = await list${BusinessName}(); | ||||
|   ${businessName}Options.value = []; | ||||
|   const data: ${BusinessName}Option = { ${treeCode}: 0, ${treeName}: '顶级节点', children: [] }; | ||||
|   data.children = proxy?.handleTree<${BusinessName}Option>(res.data, "${treeCode}", "${treeParentCode}"); | ||||
|   ${businessName}Options.value.push(data); | ||||
| } | ||||
|  | ||||
| // 取消按钮 | ||||
| const cancel = () => { | ||||
|   reset(); | ||||
|   dialog.visible = false; | ||||
| } | ||||
|  | ||||
| // 表单重置 | ||||
| const reset = () => { | ||||
|   form.value = {...initFormData} | ||||
|   ${businessName}FormRef.value?.resetFields(); | ||||
| } | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   getList(); | ||||
| } | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
|   dateRange${AttrName}.value = ['', '']; | ||||
| #end | ||||
| #end | ||||
|   queryFormRef.value?.resetFields(); | ||||
|   handleQuery(); | ||||
| } | ||||
|  | ||||
| /** 新增按钮操作 */ | ||||
| const handleAdd = (row?: ${BusinessName}VO) => { | ||||
|   reset(); | ||||
|   getTreeselect(); | ||||
|   if (row != null && row.${treeCode}) { | ||||
|     form.value.${treeParentCode} = row.${treeCode}; | ||||
|   } else { | ||||
|     form.value.${treeParentCode} = 0; | ||||
|   } | ||||
|   dialog.visible = true; | ||||
|   dialog.title = "添加${functionName}"; | ||||
| } | ||||
|  | ||||
| /** 展开/折叠操作 */ | ||||
| const handleToggleExpandAll = () => { | ||||
|   isExpandAll.value = !isExpandAll.value; | ||||
|   toggleExpandAll(${businessName}List.value, isExpandAll.value) | ||||
| } | ||||
|  | ||||
| /** 展开/折叠操作 */ | ||||
| const toggleExpandAll = (data: ${BusinessName}VO[], status: boolean) => { | ||||
|   data.forEach((item) => { | ||||
|     ${businessName}TableRef.value?.toggleRowExpansion(item, status) | ||||
|     if (item.children && item.children.length > 0) toggleExpandAll(item.children, status) | ||||
|   }) | ||||
| } | ||||
|  | ||||
| /** 修改按钮操作 */ | ||||
| const handleUpdate = async (row: ${BusinessName}VO) => { | ||||
|   reset(); | ||||
|   await getTreeselect(); | ||||
|   if (row != null) { | ||||
|     form.value.${treeParentCode} = row.${treeParentCode}; | ||||
|   } | ||||
|   const res = await get${BusinessName}(row.${pkColumn.javaField}); | ||||
|   Object.assign(form.value, res.data); | ||||
| #foreach ($column in $columns) | ||||
|   #if($column.htmlType == "checkbox") | ||||
|   form.value.$column.javaField = form.value.${column.javaField}.split(","); | ||||
|   #end | ||||
| #end | ||||
|   dialog.visible = true; | ||||
|   dialog.title = "修改${functionName}"; | ||||
| } | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
|   ${businessName}FormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       buttonLoading.value = true; | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "checkbox") | ||||
|       form.value.$column.javaField = form.value.${column.javaField}.join(","); | ||||
| #end | ||||
| #end | ||||
|       if (form.value.${pkColumn.javaField}) { | ||||
|         await update${BusinessName}(form.value).finally(() => buttonLoading.value = false); | ||||
|       } else { | ||||
|         await add${BusinessName}(form.value).finally(() => buttonLoading.value = false); | ||||
|       } | ||||
|       proxy?.#[[$modal]]#.msgSuccess("操作成功"); | ||||
|       dialog.visible = false; | ||||
|       getList(); | ||||
|     } | ||||
|   }); | ||||
| } | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (row: ${BusinessName}VO) => { | ||||
|   await proxy?.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + row.${pkColumn.javaField} + '"的数据项?'); | ||||
|   loading.value = true; | ||||
|   await del${BusinessName}(row.${pkColumn.javaField}).finally(() => loading.value = false); | ||||
|   await getList(); | ||||
|   proxy?.#[[$modal]]#.msgSuccess("删除成功"); | ||||
| } | ||||
|  | ||||
| onMounted(() => { | ||||
|   getList(); | ||||
| }); | ||||
| </script> | ||||
| @ -0,0 +1,459 @@ | ||||
| <template> | ||||
|   <div class="p-2"> | ||||
|     <transition :enter-active-class="proxy?.animate.searchAnimate.enter" :leave-active-class="proxy?.animate.searchAnimate.leave"> | ||||
|       <div v-show="showSearch" class="mb-[10px]"> | ||||
|         <el-card shadow="hover"> | ||||
|           <el-form ref="queryFormRef" :model="queryParams" :inline="true"> | ||||
| #foreach($column in $columns) | ||||
| #if($column.query) | ||||
| #set($dictType=$column.dictType) | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #if($column.htmlType == "input" || $column.htmlType == "textarea") | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-input v-model="queryParams.${column.javaField}" placeholder="请输入${comment}" clearable @keyup.enter="handleQuery" /> | ||||
|             </el-form-item> | ||||
| #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && "" != $dictType) | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable > | ||||
|                 <el-option v-for="dict in ${dictType}" :key="dict.value" :label="dict.label" :value="dict.value"/> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| #elseif(($column.htmlType == "select" || $column.htmlType == "radio") && $dictType) | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-select v-model="queryParams.${column.javaField}" placeholder="请选择${comment}" clearable > | ||||
|                 <el-option label="请选择字典生成" value="" /> | ||||
|               </el-select> | ||||
|             </el-form-item> | ||||
| #elseif($column.htmlType == "datetime" && $column.queryType != "BETWEEN") | ||||
|             <el-form-item label="${comment}" prop="${column.javaField}"> | ||||
|               <el-date-picker clearable | ||||
|                 v-model="queryParams.${column.javaField}" | ||||
|                 type="date" | ||||
|                 value-format="YYYY-MM-DD" | ||||
|                 placeholder="请选择${comment}" | ||||
|               /> | ||||
|             </el-form-item> | ||||
| #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
|             <el-form-item label="${comment}" style="width: 308px"> | ||||
|               <el-date-picker | ||||
|                 v-model="dateRange${AttrName}" | ||||
|                 value-format="YYYY-MM-DD HH:mm:ss" | ||||
|                 type="daterange" | ||||
|                 range-separator="-" | ||||
|                 start-placeholder="开始日期" | ||||
|                 end-placeholder="结束日期" | ||||
|                 :default-time="[new Date(2000, 1, 1, 0, 0, 0), new Date(2000, 1, 1, 23, 59, 59)]" | ||||
|               /> | ||||
|             </el-form-item> | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|             <el-form-item> | ||||
|               <el-button type="primary" icon="Search" @click="handleQuery">搜索</el-button> | ||||
|               <el-button icon="Refresh" @click="resetQuery">重置</el-button> | ||||
|             </el-form-item> | ||||
|           </el-form> | ||||
|         </el-card> | ||||
|       </div> | ||||
|     </transition> | ||||
|  | ||||
|     <el-card shadow="never"> | ||||
|       <template #header> | ||||
|         <el-row :gutter="10" class="mb8"> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="primary" plain icon="Plus" @click="handleAdd" v-hasPermi="['${moduleName}:${businessName}:add']">新增</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="success" plain icon="Edit" :disabled="single" @click="handleUpdate()" v-hasPermi="['${moduleName}:${businessName}:edit']">修改</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="danger" plain icon="Delete" :disabled="multiple" @click="handleDelete()" v-hasPermi="['${moduleName}:${businessName}:remove']">删除</el-button> | ||||
|           </el-col> | ||||
|           <el-col :span="1.5"> | ||||
|             <el-button type="warning" plain icon="Download" @click="handleExport" v-hasPermi="['${moduleName}:${businessName}:export']">导出</el-button> | ||||
|           </el-col> | ||||
|           <right-toolbar v-model:showSearch="showSearch" @queryTable="getList"></right-toolbar> | ||||
|         </el-row> | ||||
|       </template> | ||||
|  | ||||
|       <el-table v-loading="loading" :data="${businessName}List" @selection-change="handleSelectionChange"> | ||||
|         <el-table-column type="selection" width="55" align="center" /> | ||||
| #foreach($column in $columns) | ||||
| #set($javaField=$column.javaField) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #if($column.pk) | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}" v-if="${column.list}" /> | ||||
| #elseif($column.list && $column.htmlType == "datetime") | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}" width="180"> | ||||
|           <template #default="scope"> | ||||
|             <span>{{ parseTime(scope.row.${javaField}, '{y}-{m}-{d}') }}</span> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
| #elseif($column.list && $column.htmlType == "imageUpload") | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}Url" width="100"> | ||||
|           <template #default="scope"> | ||||
|             <image-preview :src="scope.row.${javaField}Url" :width="50" :height="50"/> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
| #elseif($column.list && $column.dictType && "" != $column.dictType) | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}"> | ||||
|           <template #default="scope"> | ||||
| #if($column.htmlType == "checkbox") | ||||
|             <dict-tag :options="${column.dictType}" :value="scope.row.${javaField} ? scope.row.${javaField}.split(',') : []"/> | ||||
| #else | ||||
|             <dict-tag :options="${column.dictType}" :value="scope.row.${javaField}"/> | ||||
| #end | ||||
|           </template> | ||||
|         </el-table-column> | ||||
| #elseif($column.list && "" != $javaField) | ||||
|         <el-table-column label="${comment}" align="center" prop="${javaField}" /> | ||||
| #end | ||||
| #end | ||||
|         <el-table-column label="操作" align="center" class-name="small-padding fixed-width"> | ||||
|           <template #default="scope"> | ||||
|             <el-tooltip content="修改" placement="top"> | ||||
|               <el-button link type="primary" icon="Edit" @click="handleUpdate(scope.row)" v-hasPermi="['${moduleName}:${businessName}:edit']"></el-button> | ||||
|             </el-tooltip> | ||||
|             <el-tooltip content="删除" placement="top"> | ||||
|               <el-button link type="primary" icon="Delete" @click="handleDelete(scope.row)" v-hasPermi="['${moduleName}:${businessName}:remove']"></el-button> | ||||
|             </el-tooltip> | ||||
|           </template> | ||||
|         </el-table-column> | ||||
|       </el-table> | ||||
|  | ||||
|       <pagination v-show="total > 0" :total="total" v-model:page="queryParams.pageNum" v-model:limit="queryParams.pageSize" @pagination="getList" /> | ||||
|     </el-card> | ||||
|     <!-- 添加或修改${functionName}对话框 --> | ||||
|     <el-dialog :title="dialog.title" v-model="dialog.visible" width="500px" append-to-body> | ||||
|       <el-form ref="${businessName}FormRef" :model="form" :rules="rules" label-width="80px"> | ||||
| #foreach($column in $columns) | ||||
| #set($field=$column.javaField) | ||||
| #if(($column.insert || $column.edit) && !$column.pk) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
| #set($dictType=$column.dictType) | ||||
| #if($column.htmlType == "input") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-input v-model="form.${field}" placeholder="请输入${comment}" /> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "imageUpload") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <image-upload v-model="form.${field}"/> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "fileUpload") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <file-upload v-model="form.${field}"/> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "editor") | ||||
|         <el-form-item label="${comment}"> | ||||
|           <editor v-model="form.${field}" :min-height="192"/> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "select" && "" != $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-select v-model="form.${field}" placeholder="请选择${comment}"> | ||||
|             <el-option | ||||
|                 v-for="dict in ${dictType}" | ||||
|                 :key="dict.value" | ||||
|                 :label="dict.label" | ||||
| #if($column.javaType == "Integer" || $column.javaType == "Long") | ||||
|                 :value="parseInt(dict.value)" | ||||
| #else | ||||
|                 :value="dict.value" | ||||
| #end | ||||
|             ></el-option> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "select" && $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-select v-model="form.${field}" placeholder="请选择${comment}"> | ||||
|             <el-option label="请选择字典生成" value="" /> | ||||
|           </el-select> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "checkbox" && "" != $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-checkbox-group v-model="form.${field}"> | ||||
|             <el-checkbox | ||||
|                 v-for="dict in ${dictType}" | ||||
|                 :key="dict.value" | ||||
|                 :label="dict.value"> | ||||
|                 {{dict.label}} | ||||
|             </el-checkbox> | ||||
|           </el-checkbox-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "checkbox" && $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-checkbox-group v-model="form.${field}"> | ||||
|             <el-checkbox>请选择字典生成</el-checkbox> | ||||
|           </el-checkbox-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "radio" && "" != $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-radio-group v-model="form.${field}"> | ||||
|             <el-radio | ||||
|               v-for="dict in ${dictType}" | ||||
|               :key="dict.value" | ||||
| #if($column.javaType == "Integer" || $column.javaType == "Long") | ||||
|               :value="parseInt(dict.value)" | ||||
| #else | ||||
|               :value="dict.value" | ||||
| #end | ||||
|             >{{dict.label}}</el-radio> | ||||
|           </el-radio-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "radio" && $dictType) | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-radio-group v-model="form.${field}"> | ||||
|             <el-radio value="1">请选择字典生成</el-radio> | ||||
|           </el-radio-group> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "datetime") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|           <el-date-picker clearable | ||||
|             v-model="form.${field}" | ||||
|             type="datetime" | ||||
|             value-format="YYYY-MM-DD HH:mm:ss" | ||||
|             placeholder="请选择${comment}"> | ||||
|           </el-date-picker> | ||||
|         </el-form-item> | ||||
| #elseif($column.htmlType == "textarea") | ||||
|         <el-form-item label="${comment}" prop="${field}"> | ||||
|             <el-input v-model="form.${field}" type="textarea" placeholder="请输入内容" /> | ||||
|         </el-form-item> | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|       </el-form> | ||||
|       <template #footer> | ||||
|         <div class="dialog-footer"> | ||||
|           <el-button :loading="buttonLoading" type="primary" @click="submitForm">确 定</el-button> | ||||
|           <el-button @click="cancel">取 消</el-button> | ||||
|         </div> | ||||
|       </template> | ||||
|     </el-dialog> | ||||
|   </div> | ||||
| </template> | ||||
|  | ||||
| <script setup name="${BusinessName}" lang="ts"> | ||||
| import { list${BusinessName}, get${BusinessName}, del${BusinessName}, add${BusinessName}, update${BusinessName} } from '@/api/${moduleName}/${businessName}'; | ||||
| import { ${BusinessName}VO, ${BusinessName}Query, ${BusinessName}Form } from '@/api/${moduleName}/${businessName}/types'; | ||||
|  | ||||
| const { proxy } = getCurrentInstance() as ComponentInternalInstance; | ||||
| #if(${dicts} != '') | ||||
| #set($dictsNoSymbol=$dicts.replace("'", "")) | ||||
| const { ${dictsNoSymbol} } = toRefs<any>(proxy?.useDict(${dicts})); | ||||
| #end | ||||
|  | ||||
| const ${businessName}List = ref<${BusinessName}VO[]>([]); | ||||
| const buttonLoading = ref(false); | ||||
| const loading = ref(true); | ||||
| const showSearch = ref(true); | ||||
| const ids = ref<Array<string | number>>([]); | ||||
| const single = ref(true); | ||||
| const multiple = ref(true); | ||||
| const total = ref(0); | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
| const dateRange${AttrName} = ref<[DateModelType, DateModelType]>(['', '']); | ||||
| #end | ||||
| #end | ||||
|  | ||||
| const queryFormRef = ref<ElFormInstance>(); | ||||
| const ${businessName}FormRef = ref<ElFormInstance>(); | ||||
|  | ||||
| const dialog = reactive<DialogOption>({ | ||||
|   visible: false, | ||||
|   title: '' | ||||
| }); | ||||
|  | ||||
| const initFormData: ${BusinessName}Form = { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.insert || $column.edit) | ||||
| #if($column.htmlType == "checkbox") | ||||
|   $column.javaField: []#if($foreach.count != $columns.size()),#end | ||||
| #else | ||||
|   $column.javaField: undefined#if($foreach.count != $columns.size()),#end | ||||
| #end | ||||
| #end | ||||
| #end | ||||
| } | ||||
| const data = reactive<PageData<${BusinessName}Form, ${BusinessName}Query>>({ | ||||
|   form: {...initFormData}, | ||||
|   queryParams: { | ||||
|     pageNum: 1, | ||||
|     pageSize: 10, | ||||
| #foreach ($column in $columns) | ||||
| #if($column.query) | ||||
| #if($column.htmlType != "datetime" || $column.queryType != "BETWEEN") | ||||
|     $column.javaField: undefined, | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|     params: { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.query) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
|       $column.javaField: undefined#if($foreach.count != $columns.size()),#end | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|     } | ||||
|   }, | ||||
|   rules: { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.insert || $column.edit) | ||||
| #if($column.required) | ||||
| #set($parentheseIndex=$column.columnComment.indexOf("(")) | ||||
| #if($parentheseIndex != -1) | ||||
| #set($comment=$column.columnComment.substring(0, $parentheseIndex)) | ||||
| #else | ||||
| #set($comment=$column.columnComment) | ||||
| #end | ||||
|     $column.javaField: [ | ||||
|       { required: true, message: "$comment不能为空", trigger: #if($column.htmlType == "select" || $column.htmlType == "radio")"change"#else"blur"#end } | ||||
|     ]#if($foreach.count != $columns.size()),#end | ||||
| #end | ||||
| #end | ||||
| #end | ||||
|   } | ||||
| }); | ||||
|  | ||||
| const { queryParams, form, rules } = toRefs(data); | ||||
|  | ||||
| /** 查询${functionName}列表 */ | ||||
| const getList = async () => { | ||||
|   loading.value = true; | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
|   queryParams.value.params = {}; | ||||
| #break | ||||
| #end | ||||
| #end | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
|   proxy?.addDateRange(queryParams.value, dateRange${AttrName}.value, '${AttrName}'); | ||||
| #end | ||||
| #end | ||||
|   const res = await list${BusinessName}(queryParams.value); | ||||
|   ${businessName}List.value = res.rows; | ||||
|   total.value = res.total; | ||||
|   loading.value = false; | ||||
| } | ||||
|  | ||||
| /** 取消按钮 */ | ||||
| const cancel = () => { | ||||
|   reset(); | ||||
|   dialog.visible = false; | ||||
| } | ||||
|  | ||||
| /** 表单重置 */ | ||||
| const reset = () => { | ||||
|   form.value = {...initFormData}; | ||||
|   ${businessName}FormRef.value?.resetFields(); | ||||
| } | ||||
|  | ||||
| /** 搜索按钮操作 */ | ||||
| const handleQuery = () => { | ||||
|   queryParams.value.pageNum = 1; | ||||
|   getList(); | ||||
| } | ||||
|  | ||||
| /** 重置按钮操作 */ | ||||
| const resetQuery = () => { | ||||
| #foreach ($column in $columns) | ||||
| #if($column.htmlType == "datetime" && $column.queryType == "BETWEEN") | ||||
| #set($AttrName=$column.javaField.substring(0,1).toUpperCase() + ${column.javaField.substring(1)}) | ||||
|   dateRange${AttrName}.value = ['', '']; | ||||
| #end | ||||
| #end | ||||
|   queryFormRef.value?.resetFields(); | ||||
|   handleQuery(); | ||||
| } | ||||
|  | ||||
| /** 多选框选中数据 */ | ||||
| const handleSelectionChange = (selection: ${BusinessName}VO[]) => { | ||||
|   ids.value = selection.map(item => item.${pkColumn.javaField}); | ||||
|   single.value = selection.length != 1; | ||||
|   multiple.value = !selection.length; | ||||
| } | ||||
|  | ||||
| /** 新增按钮操作 */ | ||||
| const handleAdd = () => { | ||||
|   reset(); | ||||
|   dialog.visible = true; | ||||
|   dialog.title = "添加${functionName}"; | ||||
| } | ||||
|  | ||||
| /** 修改按钮操作 */ | ||||
| const handleUpdate = async (row?: ${BusinessName}VO) => { | ||||
|   reset(); | ||||
|   const _${pkColumn.javaField} = row?.${pkColumn.javaField} || ids.value[0] | ||||
|   const res = await get${BusinessName}(_${pkColumn.javaField}); | ||||
|   Object.assign(form.value, res.data); | ||||
| #foreach ($column in $columns) | ||||
|   #if($column.htmlType == "checkbox") | ||||
|   form.value.$column.javaField = form.value.${column.javaField}.split(","); | ||||
|   #end | ||||
| #end | ||||
|   dialog.visible = true; | ||||
|   dialog.title = "修改${functionName}"; | ||||
| } | ||||
|  | ||||
| /** 提交按钮 */ | ||||
| const submitForm = () => { | ||||
|   ${businessName}FormRef.value?.validate(async (valid: boolean) => { | ||||
|     if (valid) { | ||||
|       buttonLoading.value = true; | ||||
|       #foreach ($column in $columns) | ||||
|         #if($column.htmlType == "checkbox") | ||||
|         form.value.$column.javaField = form.value.${column.javaField}.join(","); | ||||
|         #end | ||||
|       #end | ||||
|       if (form.value.${pkColumn.javaField}) { | ||||
|         await update${BusinessName}(form.value).finally(() =>  buttonLoading.value = false); | ||||
|       } else { | ||||
|         await add${BusinessName}(form.value).finally(() =>  buttonLoading.value = false); | ||||
|       } | ||||
|       proxy?.#[[$modal]]#.msgSuccess("操作成功"); | ||||
|       dialog.visible = false; | ||||
|       await getList(); | ||||
|     } | ||||
|   }); | ||||
| } | ||||
|  | ||||
| /** 删除按钮操作 */ | ||||
| const handleDelete = async (row?: ${BusinessName}VO) => { | ||||
|   const _${pkColumn.javaField}s = row?.${pkColumn.javaField} || ids.value; | ||||
|   await proxy?.#[[$modal]]#.confirm('是否确认删除${functionName}编号为"' + _${pkColumn.javaField}s + '"的数据项?').finally(() => loading.value = false); | ||||
|   await del${BusinessName}(_${pkColumn.javaField}s); | ||||
|   proxy?.#[[$modal]]#.msgSuccess("删除成功"); | ||||
|   await getList(); | ||||
| } | ||||
|  | ||||
| /** 导出按钮操作 */ | ||||
| const handleExport = () => { | ||||
|   proxy?.download('${moduleName}/${businessName}/export', { | ||||
|     ...queryParams.value | ||||
|   }, `${businessName}_#[[${new Date().getTime()}]]#.xlsx`) | ||||
| } | ||||
|  | ||||
| onMounted(() => { | ||||
|   getList(); | ||||
| }); | ||||
| </script> | ||||
| @ -0,0 +1,7 @@ | ||||
| <?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="${packageName}.mapper.${ClassName}Mapper"> | ||||
|  | ||||
| </mapper> | ||||
		Reference in New Issue
	
	Block a user