diff --git a/README.md b/README.md index 2ca61db3..8a08ff36 100644 --- a/README.md +++ b/README.md @@ -2,20 +2,16 @@ 2018年度最受欢迎中国开源软件评选 -请给若依/RuoYi 投票,谢谢支持。 +请给若依/RuoYi 投票,谢谢大家。 https://www.oschina.net/project/top_cn_2018?sort=1 一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。 -性别男,若依是女儿的名字。 +寓意:你若不离不弃,我必生死相依 若依基于hplus和inspinia两套后台系统模板开发。有需要可自行到群内下载。 -http://www.zi-han.net/theme/hplus - -http://webapplayers.com/inspinia_admin-v2.7.1 - > RuoYi从3.0开始,进行模块拆分,将原先的单应用转变为多模块,如需单应用,请移步 [RuoYi-fast](https://gitee.com/y_project/RuoYi-fast) > 推荐使用阿里云部署,通用云产品代金券 :[点我领取](https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof) @@ -41,7 +37,9 @@ http://webapplayers.com/inspinia_admin-v2.7.1 ## 在线体验 > admin/admin123 -地址:http://www.ruoyi.vip +演示地址:http://ruoyi.vip + +文档地址:http://doc.ruoyi.vip ## 演示图 diff --git a/ruoyi-admin/src/main/resources/application.yml b/ruoyi-admin/src/main/resources/application.yml index a1acec92..4dd6f204 100644 --- a/ruoyi-admin/src/main/resources/application.yml +++ b/ruoyi-admin/src/main/resources/application.yml @@ -126,8 +126,8 @@ xss: gen: # 作者 author: ruoyi - # 默认生成包路径 module 需改成自己的模块名称 如 system monitor tool - packageName: com.ruoyi.module + # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool + packageName: com.ruoyi.system # 自动去除表前缀,默认是true autoRemovePre: true # 表前缀(类名不会包含表前缀) diff --git a/ruoyi-admin/src/main/resources/static/ruoyi/js/common.js b/ruoyi-admin/src/main/resources/static/ruoyi/js/common.js index 64b2a834..9f56a6ac 100644 --- a/ruoyi-admin/src/main/resources/static/ruoyi/js/common.js +++ b/ruoyi-admin/src/main/resources/static/ruoyi/js/common.js @@ -68,6 +68,22 @@ $(function() { }); }); } + // laydate time-input 时间控件绑定 + if ($(".time-input").length > 0) { + layui.use('laydate', function() { + var laydate = layui.laydate; + var times = $(".time-input"); + for (var i = 0; i < times.length; i++) { + var time = times[i]; + laydate.render({ + elem: time, + theme: 'molv', + trigger: 'click', + done: function(value, date) {} + }); + } + }); + } // tree 关键字搜索绑定 if ($("#keyword").length > 0) { $("#keyword").bind("focus", function focusKey(e) { diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnConfigInfo.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnConfigInfo.java new file mode 100644 index 00000000..7deb42d3 --- /dev/null +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnConfigInfo.java @@ -0,0 +1,72 @@ +package com.ruoyi.generator.domain; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; + +/** + * 字段类型配置 由数据库字段的注释解析而来 + * 注释结构示例:{"title": "状态", "type": "dict", "value": "sys_common_status"} {"title": "登录时间", "type": "date"} + * + * @author ruoyi + * + */ +@JsonIgnoreProperties(ignoreUnknown = true) +public class ColumnConfigInfo +{ + /** + * 属性标题 + */ + private String title; + + /** + * 属性类型 dict(字典,value对应字典管理的字典类型), date(包括date) + */ + private String type; + + /** + * 属性值,参考数据类型,可为空 + */ + private String value; + + public ColumnConfigInfo() + { + super(); + } + + public ColumnConfigInfo(String title, String type, String value) + { + super(); + this.title = title; + this.type = type; + this.value = value; + } + + public String getTitle() + { + return title; + } + + public void setTitle(String title) + { + this.title = title; + } + + public String getType() + { + return type; + } + + public void setType(String type) + { + this.type = type; + } + + public String getValue() + { + return value; + } + + public void setValue(String value) + { + this.value = value; + } +} diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnInfo.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnInfo.java index 4108af6c..7afab267 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnInfo.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/domain/ColumnInfo.java @@ -1,5 +1,8 @@ package com.ruoyi.generator.domain; +import com.ruoyi.common.json.JSON; +import com.ruoyi.common.utils.StringUtils; + /** * ry数据库表列信息 * @@ -15,6 +18,9 @@ public class ColumnInfo /** 列描述 */ private String columnComment; + + /** 列配置 */ + private ColumnConfigInfo configInfo; /** Java属性类型 */ private String attrType; @@ -50,9 +56,18 @@ public class ColumnInfo return columnComment; } - public void setColumnComment(String columnComment) + public void setColumnComment(String columnComment) throws Exception { - this.columnComment = columnComment; + // 根据列描述解析列的配置信息 + if (StringUtils.isNotEmpty(columnComment) && columnComment.startsWith("{")) + { + this.configInfo = JSON.unmarshal(columnComment, ColumnConfigInfo.class); + this.columnComment = configInfo.getTitle(); + } + else + { + this.columnComment = columnComment; + } } public String getAttrName() @@ -84,4 +99,14 @@ public class ColumnInfo { this.attrType = attrType; } + + public ColumnConfigInfo getConfigInfo() + { + return configInfo; + } + + public void setConfigInfo(ColumnConfigInfo configInfo) + { + this.configInfo = configInfo; + } } diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java index 26fa726e..a925ed23 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/GenUtils.java @@ -23,7 +23,7 @@ public class GenUtils private static final String PROJECT_PATH = "main/java/com/ruoyi"; /** mybatis空间路径 */ - private static final String MYBATIS_PATH = "main/resources/mybatis"; + private static final String MYBATIS_PATH = "main/resources/mapper"; /** html空间路径 */ private static final String TEMPLATES_PATH = "main/resources/templates"; @@ -69,8 +69,9 @@ public class GenUtils velocityContext.put("primaryKey", table.getPrimaryKey()); velocityContext.put("className", table.getClassName()); velocityContext.put("classname", table.getClassname()); - velocityContext.put("moduleName", GenUtils.getModuleName(packageName)); + velocityContext.put("moduleName", getModuleName(packageName)); velocityContext.put("columns", table.getColumns()); + velocityContext.put("basePackage", getBasePackage(packageName)); velocityContext.put("package", packageName); velocityContext.put("author", Global.getAuthor()); velocityContext.put("datetime", DateUtils.getDate()); @@ -144,7 +145,7 @@ public class GenUtils if (template.contains("ServiceImpl.java.vm")) { - return javaPath + "service" + "/" + className + "ServiceImpl.java"; + return javaPath + "service" + "/" + "/impl/" + className + "ServiceImpl.java"; } if (template.contains("Controller.java.vm")) @@ -190,6 +191,13 @@ public class GenUtils return moduleName; } + public static String getBasePackage(String packageName) + { + int lastIndex = packageName.lastIndexOf("."); + String basePackage = StringUtils.substring(packageName, 0, lastIndex); + return basePackage; + } + public static String replaceKeyword(String keyword) { String keyName = keyword.replaceAll("(?:表|信息)", ""); @@ -224,6 +232,6 @@ public class GenUtils { System.out.println(StringUtils.convertToCamelCase("user_name")); System.out.println(replaceKeyword("岗位信息表")); - System.out.println(getModuleName("com.ruoyi.system")); + System.out.println(getBasePackage("com.ruoyi.system")); } } diff --git a/ruoyi-generator/src/main/resources/vm/html/add.html.vm b/ruoyi-generator/src/main/resources/vm/html/add.html.vm index 7e29b0ec..19e0d138 100644 --- a/ruoyi-generator/src/main/resources/vm/html/add.html.vm +++ b/ruoyi-generator/src/main/resources/vm/html/add.html.vm @@ -7,12 +7,33 @@ <form class="form-horizontal m" id="form-${classname}-add"> #foreach($column in $columns) #if($column.columnName != $primaryKey.columnName) +#if(!${column.configInfo}) <div class="form-group"> <label class="col-sm-3 control-label">${column.columnComment}:</label> <div class="col-sm-8"> <input id="${column.attrname}" name="${column.attrname}" class="form-control" type="text"> </div> </div> +#else +#if(${column.configInfo.type} == "dict") + <div class="form-group"> + <label class="col-sm-3 control-label">${column.columnComment}:</label> + <div class="col-sm-8"> + <select name="${column.attrname}" class="form-control m-b" th:with="type=${@dict.getType('${column.configInfo.value}')}"> + <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option> + </select> + </div> + </div> +#elseif(${column.configInfo.type} == "date") + <div class="form-group"> + <label class="col-sm-3 control-label">${column.columnComment}:</label> + <div class="col-sm-8"> + <input id="${column.attrname}" name="${column.attrname}" class="form-control time-input" type="text"> + </div> + </div> +#elseif(${column.configInfo.type} == "fk") +#end +#end #end #end </form> diff --git a/ruoyi-generator/src/main/resources/vm/html/edit.html.vm b/ruoyi-generator/src/main/resources/vm/html/edit.html.vm index e72b9388..e27119e7 100644 --- a/ruoyi-generator/src/main/resources/vm/html/edit.html.vm +++ b/ruoyi-generator/src/main/resources/vm/html/edit.html.vm @@ -8,12 +8,33 @@ <input id="${primaryKey.attrname}" name="${primaryKey.attrname}" th:field="*{${primaryKey.attrname}}" type="hidden"> #foreach($column in $columns) #if($column.columnName != $primaryKey.columnName) - <div class="form-group"> - <label class="col-sm-3 control-label">${column.columnComment}:</label> - <div class="col-sm-8"> - <input id="${column.attrname}" name="${column.attrname}" th:field="*{${column.attrname}}" class="form-control" type="text"> - </div> - </div> +#if(!${column.configInfo}) + <div class="form-group"> + <label class="col-sm-3 control-label">${column.columnComment}:</label> + <div class="col-sm-8"> + <input id="${column.attrname}" name="${column.attrname}" th:field="*{${column.attrname}}" class="form-control" type="text"> + </div> + </div> +#else +#if(${column.configInfo.type} == "dict") + <div class="form-group"> + <label class="col-sm-3 control-label">${column.columnComment}:</label> + <div class="col-sm-8"> + <select name="${column.attrname}" class="form-control m-b" th:with="type=${@dict.getType('${column.configInfo.value}')}"> + <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}" th:field="*{${column.attrname}}"></option> + </select> + </div> + </div> +#elseif(${column.configInfo.type} == "date") + <div class="form-group"> + <label class="col-sm-3 control-label">${column.columnComment}:</label> + <div class="col-sm-8"> + <input id="${column.attrname}" name="${column.attrname}" th:field="*{${column.attrname}}" class="form-control time-input" type="text"> + </div> + </div> +#elseif(${column.configInfo.type} == "fk") +#end +#end #end #end </form> diff --git a/ruoyi-generator/src/main/resources/vm/html/list.html.vm b/ruoyi-generator/src/main/resources/vm/html/list.html.vm index 2f9605d8..12b9f535 100644 --- a/ruoyi-generator/src/main/resources/vm/html/list.html.vm +++ b/ruoyi-generator/src/main/resources/vm/html/list.html.vm @@ -3,23 +3,68 @@ <meta charset="utf-8"> <head th:include="include :: header"></head> <body class="gray-bg"> - <div class="container-div"> - <div class="btn-group-sm hidden-xs" id="toolbar" role="group"> - <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="${moduleName}:${classname}:add"> - <i class="fa fa-plus"></i> 添加 - </a> - <a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="${moduleName}:${classname}:edit"> - <i class="fa fa-edit"></i> 修改 - </a> - <a class="btn btn-danger btn-del btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="${moduleName}:${classname}:remove"> - <i class="fa fa-remove"></i> 删除 - </a> - </div> + + <div class="container-div"> + <div class="row"> + <div class="col-sm-12 search-collapse"> + <form id="formId"> + <div class="select-list"> + <ul> +#foreach($column in $columns) +#if($column.columnName != $primaryKey.columnName) +#if(!${column.configInfo}) + <li> + ${column.columnComment}:<input type="text" name="${column.attrname}"/> + </li> + +#else +#if(${column.configInfo.type} == "dict") + <li> + ${column.columnComment}:<select name="${column.attrname}" th:with="type=${@dict.getType('${column.configInfo.value}')}"> + <option value="">所有</option> + <option th:each="dict : ${type}" th:text="${dict.dictLabel}" th:value="${dict.dictValue}"></option> + </select> + </li> +#elseif(${column.configInfo.type} == "date") + <li class="select-time"> + <label>${column.columnComment}: </label> + <input type="text" class="time-input" id="start${column.attrName}" placeholder="开始" name="params[begin${column.attrName}]"/> + <span>-</span> + <input type="text" class="time-input" id="end${column.attrName}" placeholder="结束" name="params[end${column.attrName}]"/> + </li> +#elseif(${column.configInfo.type} == "fk") +#end +#end +#end +#end + <li> + <a class="btn btn-primary btn-rounded btn-sm" onclick="$.table.search()"><i class="fa fa-search"></i> 搜索</a> + <a class="btn btn-warning btn-rounded btn-sm" onclick="$.form.reset()"><i class="fa fa-refresh"></i> 重置</a> + </li> + </ul> + </div> + </form> + </div> - <div class="col-sm-12 select-table table-striped"> - <table id="bootstrap-table" data-mobile-responsive="true"></table> + <div class="btn-group-sm hidden-xs" id="toolbar" role="group"> + <a class="btn btn-success" onclick="$.operate.add()" shiro:hasPermission="${moduleName}:${classname}:add"> + <i class="fa fa-plus"></i> 添加 + </a> + <a class="btn btn-primary btn-edit disabled" onclick="$.operate.edit()" shiro:hasPermission="${moduleName}:${classname}:edit"> + <i class="fa fa-edit"></i> 修改 + </a> + <a class="btn btn-danger btn-del btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="${moduleName}:${classname}:remove"> + <i class="fa fa-remove"></i> 删除 + </a> + <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="${moduleName}:${classname}:export"> + <i class="fa fa-download"></i> 导出 + </a> + </div> + <div class="col-sm-12 select-table table-striped"> + <table id="bootstrap-table" data-mobile-responsive="true"></table> + </div> </div> - </div> + </div> <div th:include="include :: footer"></div> <script th:inline="javascript"> var editFlag = [[${@permission.hasPermi('${moduleName}:${classname}:edit')}]]; @@ -32,15 +77,39 @@ createUrl: prefix + "/add", updateUrl: prefix + "/edit/{id}", removeUrl: prefix + "/remove", + exportUrl: prefix + "/export", modalName: "${tableComment}", + search: false, + showExport: true, columns: [{ checkbox: true }, #foreach($column in $columns) +#if($column.columnName == $primaryKey.columnName) { field : '${column.attrname}', - title : '${column.columnComment}' + title : '${column.columnComment}', + visible: false }, +#elseif($column.columnName != $primaryKey.columnName) +#if(${column.configInfo} && ${column.configInfo.type} == 'dict') + { + field : '${column.attrname}', + title : '${column.columnComment}', + sortable: true, + formatter: function(value, row, index) { + var datas = [[${@dict.getType('${column.configInfo.value}')}]]; + return $.table.selectDictLabel(datas, value); + } + }, +#else + { + field : '${column.attrname}', + title : '${column.columnComment}', + sortable: true + }, +#end +#end #end { title: '操作', diff --git a/ruoyi-generator/src/main/resources/vm/java/Controller.java.vm b/ruoyi-generator/src/main/resources/vm/java/Controller.java.vm index d50df9ae..4c0e748e 100644 --- a/ruoyi-generator/src/main/resources/vm/java/Controller.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/Controller.java.vm @@ -1,4 +1,4 @@ -package ${package}.web.controller; +package ${basePackage}.web.controller.${moduleName}; import java.util.List; import org.apache.shiro.authz.annotation.RequiresPermissions; @@ -17,6 +17,7 @@ import ${package}.service.I${className}Service; import com.ruoyi.framework.web.base.BaseController; import com.ruoyi.framework.web.page.TableDataInfo; import com.ruoyi.common.base.AjaxResult; +import com.ruoyi.common.utils.ExcelUtil; /** * ${tableComment} 信息操作处理 @@ -53,6 +54,20 @@ public class ${className}Controller extends BaseController return getDataTable(list); } + + /** + * 导出${tableComment}列表 + */ + @RequiresPermissions("${moduleName}:${classname}:export") + @PostMapping("/export") + @ResponseBody + public AjaxResult export(${className} ${classname}) + { + List<${className}> list = ${classname}Service.select${className}List(${classname}); + ExcelUtil<${className}> util = new ExcelUtil<${className}>(${className}.class); + return util.exportExcel(list, "${classname}"); + } + /** * 新增${tableComment} */ diff --git a/ruoyi-generator/src/main/resources/vm/java/ServiceImpl.java.vm b/ruoyi-generator/src/main/resources/vm/java/ServiceImpl.java.vm index b76f981d..540c5ab3 100644 --- a/ruoyi-generator/src/main/resources/vm/java/ServiceImpl.java.vm +++ b/ruoyi-generator/src/main/resources/vm/java/ServiceImpl.java.vm @@ -1,4 +1,4 @@ -package ${package}.service; +package ${package}.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;