diff --git a/pom.xml b/pom.xml index b4d6fe41..ddc28752 100644 --- a/pom.xml +++ b/pom.xml @@ -22,10 +22,10 @@ 1.21 3.0.0 2.3.2 - 2.2.0 - 1.4.0 + 2.2.2 + 1.4.1 1.2.79 - 5.8.6 + 6.1.2 5.10.0 2.11.0 1.4 diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java index f29d2cbe..604ca020 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java @@ -119,4 +119,12 @@ public class Jvm { return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate()); } + + /** + * 运行参数 + */ + public String getInputArgs() + { + return ManagementFactory.getRuntimeMXBean().getInputArguments().toString(); + } } diff --git a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java index 2b547432..6f8b9aa5 100644 --- a/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java +++ b/ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/SysLoginService.java @@ -17,6 +17,7 @@ import com.ruoyi.common.exception.user.CaptchaExpireException; import com.ruoyi.common.exception.user.UserPasswordNotMatchException; import com.ruoyi.common.utils.DateUtils; import com.ruoyi.common.utils.MessageUtils; +import com.ruoyi.common.utils.StringUtils; import com.ruoyi.common.utils.ServletUtils; import com.ruoyi.common.utils.ip.IpUtils; import com.ruoyi.framework.manager.AsyncManager; @@ -102,7 +103,7 @@ public class SysLoginService */ public void validateCaptcha(String username, String code, String uuid) { - String verifyKey = Constants.CAPTCHA_CODE_KEY + uuid; + String verifyKey = Constants.CAPTCHA_CODE_KEY + StringUtils.nvl(uuid, ""); String captcha = redisCache.getCacheObject(verifyKey); redisCache.deleteObject(verifyKey); if (captcha == null) diff --git a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java index 6bce127c..9ddf2650 100644 --- a/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java +++ b/ruoyi-generator/src/main/java/com/ruoyi/generator/util/VelocityUtils.java @@ -271,6 +271,23 @@ public class VelocityUtils { List columns = genTable.getColumns(); Set dicts = new HashSet(); + addDicts(dicts, columns); + if (StringUtils.isNotNull(genTable.getSubTable())) + { + List subColumns = genTable.getSubTable().getColumns(); + addDicts(dicts, subColumns); + } + return StringUtils.join(dicts, ", "); + } + + /** + * 添加字典列表 + * + * @param dicts 字典列表 + * @param columns 列集合 + */ + public static void addDicts(Set dicts, List columns) + { for (GenTableColumn column : columns) { if (!column.isSuperColumn() && StringUtils.isNotEmpty(column.getDictType()) && StringUtils.equalsAny( @@ -280,7 +297,6 @@ public class VelocityUtils dicts.add("'" + column.getDictType() + "'"); } } - return StringUtils.join(dicts, ", "); } /** diff --git a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm index e7687b7b..f034d7df 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/index.vue.vm @@ -44,7 +44,7 @@ v-model="queryParams.${column.javaField}" type="date" value-format="yyyy-MM-dd" - placeholder="选择${comment}"> + placeholder="请选择${comment}"> #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") @@ -269,7 +269,7 @@ v-model="form.${field}" type="date" value-format="yyyy-MM-dd" - placeholder="选择${comment}"> + placeholder="请选择${comment}"> #elseif($column.htmlType == "textarea") @@ -302,12 +302,39 @@ #set($comment=$column.columnComment) #end #if($column.pk || $javaField == ${subTableFkclassName}) -#elseif($column.list && "" != $javaField) - +#elseif($column.list && $column.htmlType == "input") + +#elseif($column.list && $column.htmlType == "datetime") + + + + + +#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType) + + + + + + + +#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType) + + + + + + + #end #end diff --git a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm index 08bb0711..a363ef36 100644 --- a/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm +++ b/ruoyi-generator/src/main/resources/vm/vue/v3/index.vue.vm @@ -43,7 +43,7 @@ v-model="queryParams.${column.javaField}" type="date" value-format="YYYY-MM-DD" - placeholder="选择${comment}"> + placeholder="请选择${comment}"> #elseif($column.htmlType == "datetime" && $column.queryType == "BETWEEN") @@ -260,7 +260,7 @@ v-model="form.${field}" type="date" value-format="YYYY-MM-DD" - placeholder="选择${comment}"> + placeholder="请选择${comment}"> #elseif($column.htmlType == "textarea") @@ -293,12 +293,44 @@ #set($comment=$column.columnComment) #end #if($column.pk || $javaField == ${subTableFkclassName}) -#elseif($column.list && "" != $javaField) - +#elseif($column.list && $column.htmlType == "input") + +#elseif($column.list && $column.htmlType == "datetime") + + + + + + +#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" != $column.dictType) + + + + + + + +#elseif($column.list && ($column.htmlType == "select" || $column.htmlType == "radio") && "" == $column.dictType) + + + + + + + #end #end diff --git a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java index b75fed0d..c37ff655 100644 --- a/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java +++ b/ruoyi-quartz/src/main/java/com/ruoyi/quartz/config/ScheduleConfig.java @@ -1,58 +1,57 @@ -package com.ruoyi.quartz.config; - -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.quartz.SchedulerFactoryBean; -import javax.sql.DataSource; -import java.util.Properties; - -/** - * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) - * - * @author ruoyi - */ -@Configuration -public class ScheduleConfig -{ - @Bean - public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) - { - SchedulerFactoryBean factory = new SchedulerFactoryBean(); - factory.setDataSource(dataSource); - - // quartz参数 - Properties prop = new Properties(); - prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); - prop.put("org.quartz.scheduler.instanceId", "AUTO"); - prop.put("org.quartz.jobStore.driverDelegateClass", "org.quartz.impl.jdbcjobstore.PostgreSQLDelegate"); - // 线程池配置 - prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); - prop.put("org.quartz.threadPool.threadCount", "20"); - prop.put("org.quartz.threadPool.threadPriority", "5"); - // JobStore配置 - prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); - // 集群配置 - prop.put("org.quartz.jobStore.isClustered", "true"); - prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); - prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); - prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); - - // sqlserver 启用 - // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); - prop.put("org.quartz.jobStore.misfireThreshold", "12000"); - prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); - factory.setQuartzProperties(prop); - - factory.setSchedulerName("RuoyiScheduler"); - // 延时启动 - factory.setStartupDelay(1); - factory.setApplicationContextSchedulerContextKey("applicationContextKey"); - // 可选,QuartzScheduler - // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 - factory.setOverwriteExistingJobs(true); - // 设置自动启动,默认为true - factory.setAutoStartup(true); - - return factory; - } -} +//package com.ruoyi.quartz.config; +// +//import org.springframework.context.annotation.Bean; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.quartz.SchedulerFactoryBean; +//import javax.sql.DataSource; +//import java.util.Properties; +// +///** +// * 定时任务配置(单机部署建议删除此类和qrtz数据库表,默认走内存会最高效) +// * +// * @author ruoyi +// */ +//@Configuration +//public class ScheduleConfig +//{ +// @Bean +// public SchedulerFactoryBean schedulerFactoryBean(DataSource dataSource) +// { +// SchedulerFactoryBean factory = new SchedulerFactoryBean(); +// factory.setDataSource(dataSource); +// +// // quartz参数 +// Properties prop = new Properties(); +// prop.put("org.quartz.scheduler.instanceName", "RuoyiScheduler"); +// prop.put("org.quartz.scheduler.instanceId", "AUTO"); +// // 线程池配置 +// prop.put("org.quartz.threadPool.class", "org.quartz.simpl.SimpleThreadPool"); +// prop.put("org.quartz.threadPool.threadCount", "20"); +// prop.put("org.quartz.threadPool.threadPriority", "5"); +// // JobStore配置 +// prop.put("org.quartz.jobStore.class", "org.springframework.scheduling.quartz.LocalDataSourceJobStore"); +// // 集群配置 +// prop.put("org.quartz.jobStore.isClustered", "true"); +// prop.put("org.quartz.jobStore.clusterCheckinInterval", "15000"); +// prop.put("org.quartz.jobStore.maxMisfiresToHandleAtATime", "1"); +// prop.put("org.quartz.jobStore.txIsolationLevelSerializable", "true"); +// +// // sqlserver 启用 +// // prop.put("org.quartz.jobStore.selectWithLockSQL", "SELECT * FROM {0}LOCKS UPDLOCK WHERE LOCK_NAME = ?"); +// prop.put("org.quartz.jobStore.misfireThreshold", "12000"); +// prop.put("org.quartz.jobStore.tablePrefix", "QRTZ_"); +// factory.setQuartzProperties(prop); +// +// factory.setSchedulerName("RuoyiScheduler"); +// // 延时启动 +// factory.setStartupDelay(1); +// factory.setApplicationContextSchedulerContextKey("applicationContextKey"); +// // 可选,QuartzScheduler +// // 启动时更新己存在的Job,这样就不用每次修改targetObject后删除qrtz_job_details表对应记录了 +// factory.setOverwriteExistingJobs(true); +// // 设置自动启动,默认为true +// factory.setAutoStartup(true); +// +// return factory; +// } +//} diff --git a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml index fe5fe328..4a2780dd 100644 --- a/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml +++ b/ruoyi-system/src/main/resources/mapper/system/SysMenuMapper.xml @@ -133,7 +133,7 @@ order_num = #{orderNum}, path = #{path}, component = #{component}, - query = #{query}, + `query` = #{query}, is_frame = #{isFrame}, is_cache = #{isCache}, menu_type = #{menuType}, @@ -156,7 +156,7 @@ order_num, path, component, - query, + `query`, is_frame, is_cache, menu_type, diff --git a/ruoyi-ui/src/components/Pagination/index.vue b/ruoyi-ui/src/components/Pagination/index.vue index 76d958bb..1617af00 100644 --- a/ruoyi-ui/src/components/Pagination/index.vue +++ b/ruoyi-ui/src/components/Pagination/index.vue @@ -61,6 +61,10 @@ export default { default: false } }, + data() { + return { + }; + }, computed: { currentPage: { get() { @@ -81,6 +85,9 @@ export default { }, methods: { handleSizeChange(val) { + if (this.currentPage * val > this.total) { + this.currentPage = 1 + } this.$emit('pagination', { page: this.currentPage, limit: val }) if (this.autoScroll) { scrollTo(0, 800) diff --git a/ruoyi-ui/src/permission.js b/ruoyi-ui/src/permission.js index bde52936..6bb0a1f8 100644 --- a/ruoyi-ui/src/permission.js +++ b/ruoyi-ui/src/permission.js @@ -1,53 +1,56 @@ -import router from './router' -import store from './store' -import { Message } from 'element-ui' -import NProgress from 'nprogress' -import 'nprogress/nprogress.css' -import { getToken } from '@/utils/auth' - -NProgress.configure({ showSpinner: false }) - -const whiteList = ['/login', '/auth-redirect', '/bind', '/register'] - -router.beforeEach((to, from, next) => { - NProgress.start() - if (getToken()) { - to.meta.title && store.dispatch('settings/setTitle', to.meta.title) - /* has token*/ - if (to.path === '/login') { - next({ path: '/' }) - NProgress.done() - } else { - if (store.getters.roles.length === 0) { - // 判断当前用户是否已拉取完user_info信息 - store.dispatch('GetInfo').then(() => { - store.dispatch('GenerateRoutes').then(accessRoutes => { - // 根据roles权限生成可访问的路由表 - router.addRoutes(accessRoutes) // 动态添加可访问路由表 - next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 - }) - }).catch(err => { - store.dispatch('LogOut').then(() => { - Message.error(err) - next({ path: '/' }) - }) - }) - } else { - next() - } - } - } else { - // 没有token - if (whiteList.indexOf(to.path) !== -1) { - // 在免登录白名单,直接进入 - next() - } else { - next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 - NProgress.done() - } - } -}) - -router.afterEach(() => { - NProgress.done() -}) +import router from './router' +import store from './store' +import { Message } from 'element-ui' +import NProgress from 'nprogress' +import 'nprogress/nprogress.css' +import { getToken } from '@/utils/auth' +import { isRelogin } from '@/utils/request' + +NProgress.configure({ showSpinner: false }) + +const whiteList = ['/login', '/auth-redirect', '/bind', '/register'] + +router.beforeEach((to, from, next) => { + NProgress.start() + if (getToken()) { + to.meta.title && store.dispatch('settings/setTitle', to.meta.title) + /* has token*/ + if (to.path === '/login') { + next({ path: '/' }) + NProgress.done() + } else { + if (store.getters.roles.length === 0) { + isRelogin.show = true + // 判断当前用户是否已拉取完user_info信息 + store.dispatch('GetInfo').then(() => { + isRelogin.show = false + store.dispatch('GenerateRoutes').then(accessRoutes => { + // 根据roles权限生成可访问的路由表 + router.addRoutes(accessRoutes) // 动态添加可访问路由表 + next({ ...to, replace: true }) // hack方法 确保addRoutes已完成 + }) + }).catch(err => { + store.dispatch('LogOut').then(() => { + Message.error(err) + next({ path: '/' }) + }) + }) + } else { + next() + } + } + } else { + // 没有token + if (whiteList.indexOf(to.path) !== -1) { + // 在免登录白名单,直接进入 + next() + } else { + next(`/login?redirect=${to.fullPath}`) // 否则全部重定向到登录页 + NProgress.done() + } + } +}) + +router.afterEach(() => { + NProgress.done() +}) diff --git a/ruoyi-ui/src/utils/request.js b/ruoyi-ui/src/utils/request.js index 107a28d6..e69205bc 100644 --- a/ruoyi-ui/src/utils/request.js +++ b/ruoyi-ui/src/utils/request.js @@ -9,7 +9,7 @@ import { saveAs } from 'file-saver' let downloadLoadingInstance; // 是否显示重新登录 -let isReloginShow; +export let isRelogin = { show: false }; axios.defaults.headers['Content-Type'] = 'application/json;charset=utf-8' // 创建axios实例 @@ -76,23 +76,20 @@ service.interceptors.response.use(res => { return res.data } if (code === 401) { - if (!isReloginShow) { - isReloginShow = true; + if (!isRelogin.show) { + isRelogin.show = true; MessageBox.confirm('登录状态已过期,您可以继续留在该页面,或者重新登录', '系统提示', { confirmButtonText: '重新登录', cancelButtonText: '取消', type: 'warning' } ).then(() => { - isReloginShow = false; + isRelogin.show = false; store.dispatch('LogOut').then(() => { - // 如果是登录页面不需要重新加载 - if (window.location.hash.indexOf("#/login") != 0) { - location.href = '/index'; - } + location.href = '/index'; }) }).catch(() => { - isReloginShow = false; + isRelogin.show = false; }); } return Promise.reject('无效的会话,或者会话已过期,请重新登录。') diff --git a/ruoyi-ui/src/utils/ruoyi.js b/ruoyi-ui/src/utils/ruoyi.js index 8e3cb0ce..7e6eccd1 100644 --- a/ruoyi-ui/src/utils/ruoyi.js +++ b/ruoyi-ui/src/utils/ruoyi.js @@ -70,6 +70,9 @@ export function addDateRange(params, dateRange, propName) { // 回显数据字典 export function selectDictLabel(datas, value) { + if (value === undefined) { + return ""; + } var actions = []; Object.keys(datas).some((key) => { if (datas[key].value == ('' + value)) { @@ -77,23 +80,31 @@ export function selectDictLabel(datas, value) { return true; } }) + if (actions.length === 0) { + actions.push(value); + } return actions.join(''); } // 回显数据字典(字符串数组) export function selectDictLabels(datas, value, separator) { - if(value === undefined) { + if (value === undefined) { return ""; } var actions = []; var currentSeparator = undefined === separator ? "," : separator; var temp = value.split(currentSeparator); Object.keys(value.split(currentSeparator)).some((val) => { + var match = false; Object.keys(datas).some((key) => { if (datas[key].value == ('' + temp[val])) { actions.push(datas[key].label + currentSeparator); + match = true; } }) + if (!match) { + actions.push(temp[val] + currentSeparator); + } }) return actions.join('').substring(0, actions.join('').length - 1); } diff --git a/ruoyi-ui/src/views/monitor/job/index.vue b/ruoyi-ui/src/views/monitor/job/index.vue index 84ea6af6..eba8e0f2 100644 --- a/ruoyi-ui/src/views/monitor/job/index.vue +++ b/ruoyi-ui/src/views/monitor/job/index.vue @@ -165,7 +165,7 @@ - + 项目路径 {{ server.sys.userDir }} + + 运行参数 + {{ server.jvm.inputArgs }} + diff --git a/ruoyi-ui/src/views/system/dept/index.vue b/ruoyi-ui/src/views/system/dept/index.vue index b57f2b9d..17bc72ac 100644 --- a/ruoyi-ui/src/views/system/dept/index.vue +++ b/ruoyi-ui/src/views/system/dept/index.vue @@ -206,7 +206,7 @@ export default { email: [ { type: "email", - message: "'请输入正确的邮箱地址", + message: "请输入正确的邮箱地址", trigger: ["blur", "change"] } ], diff --git a/ruoyi-ui/src/views/system/notice/index.vue b/ruoyi-ui/src/views/system/notice/index.vue index 22b2ad5e..53bb3b41 100644 --- a/ruoyi-ui/src/views/system/notice/index.vue +++ b/ruoyi-ui/src/views/system/notice/index.vue @@ -135,7 +135,7 @@ - + - + - + - +