RuoYi 6 лет назад
Родитель
Сommit
6a592827e8
41 измененных файлов с 2004 добавлено и 5447 удалено
  1. 0 6
      README.md
  2. 0 14
      bin/run-tomcat.bat
  3. 3 2
      pom.xml
  4. 1 2
      ruoyi-admin/pom.xml
  5. 31 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java
  6. 9 0
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobController.java
  7. 3 2
      ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobLogController.java
  8. 1 1
      ruoyi-admin/src/main/resources/application.yml
  9. 25 0
      ruoyi-admin/src/main/resources/static/ruoyi/js/common.js
  10. 19 1
      ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js
  11. 2 2
      ruoyi-admin/src/main/resources/templates/include.html
  12. 2 7
      ruoyi-admin/src/main/resources/templates/index.html
  13. 2 2
      ruoyi-admin/src/main/resources/templates/login.html
  14. 34 4
      ruoyi-admin/src/main/resources/templates/main.html
  15. 2 2
      ruoyi-admin/src/main/resources/templates/monitor/job/add.html
  16. 56 10
      ruoyi-admin/src/main/resources/templates/monitor/job/detail.html
  17. 2 2
      ruoyi-admin/src/main/resources/templates/monitor/job/edit.html
  18. 7 6
      ruoyi-admin/src/main/resources/templates/monitor/job/job.html
  19. 1 0
      ruoyi-admin/src/main/resources/templates/monitor/logininfor/logininfor.html
  20. 1 0
      ruoyi-admin/src/main/resources/templates/monitor/online/online.html
  21. 1 0
      ruoyi-admin/src/main/resources/templates/monitor/operlog/operlog.html
  22. 254 0
      ruoyi-admin/src/main/resources/templates/monitor/server/server.html
  23. 1 1
      ruoyi-common/pom.xml
  24. 109 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java
  25. 32 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java
  26. 26 0
      ruoyi-common/src/main/java/com/ruoyi/common/utils/IpUtils.java
  27. 19 3
      ruoyi-framework/pom.xml
  28. 1 6
      ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/web/filter/sync/SyncOnlineSessionFilter.java
  29. 238 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java
  30. 101 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java
  31. 122 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java
  32. 61 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java
  33. 84 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java
  34. 114 0
      ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java
  35. 1 1
      ruoyi-generator/pom.xml
  36. 1 1
      ruoyi-quartz/pom.xml
  37. 14 1
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java
  38. 2 0
      ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleJob.java
  39. 1 1
      ruoyi-system/pom.xml
  40. 0 4851
      sql/ruoyi.pdb
  41. 621 519
      sql/ry_20181124.sql

+ 0 - 6
README.md

@@ -1,11 +1,5 @@
 ## 平台简介
 
-
-2018年度最受欢迎中国开源软件评选  
-请给若依/RuoYi 投票,谢谢大家。  
-https://www.oschina.net/project/top_cn_2018?sort=1
-
-
 一直想做一款后台管理系统,看了很多优秀的开源项目但是发现没有合适的。于是利用空闲休息时间开始自己写了一套后台系统。如此有了若依。她可以用于所有的Web应用程序,如网站管理后台,网站会员中心,CMS,CRM,OA。所有前端后台代码封装过后十分精简易上手,出错概率低。同时支持移动客户端访问。系统会陆续更新一些实用功能。
 
 寓意:你若不离不弃,我必生死相依

+ 0 - 14
bin/run-tomcat.bat

@@ -1,14 +0,0 @@
-@echo off
-echo.
-echo [ÐÅÏ¢] ʹÓà Spring Boot Tomcat ÔËÐÐ Web ¹¤³Ì¡£
-echo.
-
-%~d0
-cd %~dp0
-
-cd ..
-title %cd%
-set MAVEN_OPTS=%MAVEN_OPTS% -Xms256m -Xmx1024m -XX:MetaspaceSize=128m -XX:MaxMetaspaceSize=512m
-call mvn clean spring-boot:run -Dmaven.test.skip=true -U
-
-pause

+ 3 - 2
pom.xml

@@ -6,14 +6,14 @@
 	
     <groupId>com.ruoyi</groupId>
     <artifactId>ruoyi</artifactId>
-    <version>3.0</version>
+    <version>3.1</version>
 
     <name>ruoyi</name>
 	<url>http://www.ruoyi.vip</url>
     <description>若依管理系统</description>
     
     <properties>
-	    <ruoyi.version>3.0</ruoyi.version>
+	    <ruoyi.version>3.1</ruoyi.version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
 		<java.version>1.8</java.version>
@@ -25,6 +25,7 @@
 		<kaptcha.version>2.3.2</kaptcha.version>
 		<swagger.version>2.7.0</swagger.version>
 		<pagehelper.boot.version>1.2.5</pagehelper.boot.version>
+		<oshi.version>3.9.1</oshi.version>
 	</properties>
 	
     <dependencyManagement>

+ 1 - 2
ruoyi-admin/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>ruoyi</artifactId>
         <groupId>com.ruoyi</groupId>
-        <version>3.0</version>
+        <version>3.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 	<packaging>jar</packaging>
@@ -44,7 +44,6 @@
             <groupId>com.ruoyi</groupId>
             <artifactId>ruoyi-framework</artifactId>
             <version>${ruoyi.version}</version>
-
         </dependency>
         
     </dependencies>

+ 31 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/ServerController.java

@@ -0,0 +1,31 @@
+package com.ruoyi.web.controller.monitor;
+
+import org.apache.shiro.authz.annotation.RequiresPermissions;
+import org.springframework.stereotype.Controller;
+import org.springframework.ui.ModelMap;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.RequestMapping;
+import com.ruoyi.framework.web.base.BaseController;
+import com.ruoyi.framework.web.domain.Server;
+
+/**
+ * 服务器监控
+ * 
+ * @author ruoyi
+ */
+@Controller
+@RequestMapping("/monitor/server")
+public class ServerController extends BaseController
+{
+    private String prefix = "monitor/server";
+
+    @RequiresPermissions("monitor:server:view")
+    @GetMapping()
+    public String server(ModelMap mmap) throws Exception
+    {
+        Server server = new Server();
+        server.copyTo();
+        mmap.put("server", server);
+        return prefix + "/server";
+    }
+}

+ 9 - 0
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobController.java

@@ -80,6 +80,15 @@ public class SysJobController extends BaseController
         }
     }
 
+    @RequiresPermissions("monitor:job:detail")
+    @GetMapping("/detail/{jobId}")
+    public String detail(@PathVariable("jobId") Long jobId, ModelMap mmap)
+    {
+        mmap.put("name", "job");
+        mmap.put("job", jobService.selectJobById(jobId));
+        return prefix + "/detail";
+    }
+
     /**
      * 任务调度状态修改
      */

+ 3 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/monitor/SysJobLogController.java

@@ -69,15 +69,16 @@ public class SysJobLogController extends BaseController
     {
         return toAjax(jobLogService.deleteJobLogByIds(ids));
     }
-    
+
     @RequiresPermissions("monitor:job:detail")
     @GetMapping("/detail/{jobLogId}")
     public String detail(@PathVariable("jobLogId") Long jobLogId, ModelMap mmap)
     {
+        mmap.put("name", "jobLog");
         mmap.put("jobLog", jobLogService.selectJobLogById(jobLogId));
         return prefix + "/detail";
     }
-    
+
     @Log(title = "调度日志", businessType = BusinessType.CLEAN)
     @RequiresPermissions("monitor:job:remove")
     @PostMapping("/clean")

+ 1 - 1
ruoyi-admin/src/main/resources/application.yml

@@ -3,7 +3,7 @@ ruoyi:
   # 名称
   name: RuoYi
   # 版本
-  version: 3.0.0
+  version: 3.1.0
   # 版权年份
   copyrightYear: 2018
   # 文件上传路径

+ 25 - 0
ruoyi-admin/src/main/resources/static/ruoyi/js/common.js

@@ -115,6 +115,15 @@ $(function() {
 	})
 });
 
+/** 刷新选项卡 */
+var refreshItem = function(){
+    var topWindow = $(window.parent.document);
+	var currentId = $('.page-tabs-content', topWindow).find('.active').attr('data-id');
+	var target = $('.RuoYi_iframe[data-id="' + currentId + '"]', topWindow);
+    var url = target.attr('src');
+    target.attr('src', url).ready();
+}
+
 /** 创建选项卡 */
 function createMenuItem(dataUrl, menuName) {
     dataIndex = $.common.random(1,100),
@@ -154,6 +163,22 @@ function createMenuItem(dataUrl, menuName) {
     return false;
 }
 
+//日志打印封装处理
+var log = {
+    log: function (msg) {
+    	console.log(msg);
+    },
+    info: function(msg) {
+    	console.info(msg);
+    },
+    warn: function(msg) {
+    	console.warn(msg);
+    },
+    error: function(msg) {
+    	console.error(msg);
+    }
+};
+
 /** 设置全局ajax处理 */
 $.ajaxSetup({
     complete: function(XMLHttpRequest, textStatus) {

+ 19 - 1
ruoyi-admin/src/main/resources/static/ruoyi/js/ry-ui.js

@@ -17,6 +17,7 @@
                 _sortOrder = $.common.isEmpty(options.sortOrder) ? "asc" : options.sortOrder;
                 _sortName = $.common.isEmpty(options.sortName) ? "" : options.sortName;
                 _striped = $.common.isEmpty(options.striped) ? false : options.striped;
+                _escape = $.common.isEmpty(options.escape) ? false : options.escape;
                 $('#bootstrap-table').bootstrapTable({
                     url: options.url,                                   // 请求后台的URL(*)
                     contentType: "application/x-www-form-urlencoded",   // 编码类型
@@ -31,9 +32,10 @@
                     pageNumber: 1,                                      // 初始化加载第一页,默认第一页
                     pageSize: 10,                                       // 每页的记录行数(*) 
                     pageList: [10, 25, 50],                             // 可供选择的每页的行数(*)
+                    escape: _escape,                                    // 转义HTML字符串
                     iconSize: 'outline',                                // 图标大小:undefined默认的按钮尺寸 xs超小按钮sm小按钮lg大按钮
         	        toolbar: '#toolbar',                                // 指定工作栏
-                    sidePagination: "server",                           // 启用服务端分页 
+                    sidePagination: "server",                           // 启用服务端分页
                     search: $.common.visible(options.search),           // 是否显示搜索框功能
                     showSearch: $.common.visible(options.showSearch),   // 是否显示检索信息
                     showRefresh: $.common.visible(options.showRefresh), // 是否显示刷新按钮
@@ -124,6 +126,14 @@
                     }
                 });
                 return actions.join('');
+            },
+            // 显示表格指定列
+            showColumn: function(column) {
+                $("#bootstrap-table").bootstrapTable('showColumn', column);
+            },
+            // 隐藏表格指定列
+            hideColumn: function(column) {
+            	$("#bootstrap-table").bootstrapTable('hideColumn', column);
             }
         },
         // 表格树封装处理
@@ -780,6 +790,14 @@
             // 指定随机数返回
             random: function (min, max) {
                 return Math.floor((Math.random() * max) + min);
+            },
+            startWith: function(value, start) {
+                var reg = new RegExp("^" + start);
+                return reg.test(value)
+            },
+            endWith: function(value, end) {
+                var reg = new RegExp(end + "$");
+                return reg.test(value)
             }
         }
     });

+ 2 - 2
ruoyi-admin/src/main/resources/templates/include.html

@@ -38,8 +38,8 @@
 	<script th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
 	<script th:src="@{/ajax/libs/layer/layer.min.js}"></script>
 	<script th:src="@{/ajax/libs/layui/layui.js}"></script>
-	<script th:src="@{/ruoyi/js/common.js?v=3.0.0}"></script>
-	<script th:src="@{/ruoyi/js/ry-ui.js?v=3.0.0}"></script>
+	<script th:src="@{/ruoyi/js/common.js?v=3.1.0}"></script>
+	<script th:src="@{/ruoyi/js/ry-ui.js?v=3.1.0}"></script>
 	<script src="http://tajs.qq.com/stats?sId=62048022"></script>
 	<script th:inline="javascript"> var ctx = [[@{/}]]; </script>
 </div>

+ 2 - 7
ruoyi-admin/src/main/resources/templates/index.html

@@ -15,7 +15,7 @@
     <link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
     <link th:href="@{/css/animate.css}" rel="stylesheet"/>
     <link th:href="@{/css/style.css}" rel="stylesheet"/>
-    <link th:href="@{/ruoyi/css/ry-ui.css?v=3.0.0}" rel="stylesheet"/>
+    <link th:href="@{/ruoyi/css/ry-ui.css?v=3.1.0}" rel="stylesheet"/>
     <style type="text/css">
         .nav > li:hover .dropdown-menu {display: block;}
         #content-main.max { height: calc(100% - 110px); overflow: hidden; width: 100%; height: 100%; left: 0px; position: absolute; top: 0px; z-index: 9998; margin: 0; }
@@ -81,11 +81,6 @@
                     <a class="navbar-minimalize minimalize-styl-2 btn btn-default " href="#" title="收起菜单">
                     	<i class="fa fa-bars"></i>
                     </a>
-                    <form role="search" class="navbar-form-custom" method="post" action="">
-                        <div class="form-group">
-                            <input type="text" placeholder="请输入您需要查找的内容 …" class="form-control" name="top-search" id="top-search">
-                        </div>
-                    </form>
                 </div>
                 <ul class="nav navbar-top-links navbar-right welcome-message">
 	                <li>
@@ -141,7 +136,7 @@
 <script th:src="@{/js/plugins/slimscroll/jquery.slimscroll.min.js}"></script>
 <script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
 <script src="http://tajs.qq.com/stats?sId=62048022"></script>
-<script th:src="@{/ruoyi/js/ry-ui.js?v=3.0.0}"></script>
+<script th:src="@{/ruoyi/js/ry-ui.js?v=3.1.0}"></script>
 <script th:src="@{/ruoyi/index.js}"></script>
 <script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
 </body>

+ 2 - 2
ruoyi-admin/src/main/resources/templates/login.html

@@ -12,7 +12,7 @@
     <link href="../static/css/style.css" th:href="@{css/style.css}" rel="stylesheet"/>
     <link href="../static/css/login.min.css" th:href="@{css/login.min.css}" rel="stylesheet"/>
     <link href="../static/ajax/libs/iCheck/custom.css" th:href="@{/ajax/libs/iCheck/custom.css}" rel="stylesheet"/>
-    <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=3.0.0}" rel="stylesheet"/>
+    <link href="../static/ruoyi/css/ry-ui.css" th:href="@{/ruoyi/css/ry-ui.css?v=3.1.0}" rel="stylesheet"/>
     <!--[if lt IE 9]>
     <meta http-equiv="refresh" content="0;ie.html" />
     <![endif]-->
@@ -83,7 +83,7 @@
 <script src="../static/ajax/libs/iCheck/icheck.min.js" th:src="@{/ajax/libs/iCheck/icheck.min.js}"></script>
 <script src="../static/ajax/libs/blockUI/jquery.blockUI.js" th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
 <script src="http://tajs.qq.com/stats?sId=62048022"></script>
-<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=3.0.0}"></script>
+<script src="../static/ruoyi/js/ry-ui.js" th:src="@{/ruoyi/js/ry-ui.js?v=3.1.0}"></script>
 <script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
 </body>
 </html>

+ 34 - 4
ruoyi-admin/src/main/resources/templates/main.html

@@ -16,9 +16,9 @@
     <div class="row  border-bottom white-bg dashboard-header">
         <div class="col-sm-12">
             <blockquote class="text-warning" style="font-size:14px">
-                2018年度最受欢迎中国开源软件评选
-                <br><a target="_blank" href="https://www.oschina.net/project/top_cn_2018?sort=1">https://www.oschina.net/project/top_cn_2018?sort=1</a>
-                <h4 class="text-danger">请给若依/RuoYi 投票,谢谢支持。</h4>
+                                                        领取阿里云1888通用代金券(新老客户均可用)
+                <br><a target="_blank" href="https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof">https://promotion.aliyun.com/ntms/yunparter/invite.html?userCode=brki8iof</a>
+                <h4 class="text-danger">云产品通用红包,可叠加官网常规优惠使用。</h4>
             </blockquote>
 
             <hr>
@@ -94,13 +94,43 @@
                     <div class="ibox-content no-padding">
                         <div class="panel-body">
                             <div class="panel-group" id="version">
+                            <div class="panel panel-default">
+								<div class="panel-heading">
+								   <h5 class="panel-title">
+									   <a data-toggle="collapse" data-parent="#version" href="#v31">v3.1.0</a><code class="pull-right">2018.12.03</code>
+								   </h5>
+								</div>
+								<div id="v31" class="panel-collapse collapse in">
+									<div class="panel-body">
+									   <ol>
+											<li>新增内网不获取IP地址</li>
+											<li>新增cron表达式有效校验</li>
+											<li>定时任务新增详细信息</li>
+											<li>定时任务默认策略修改(不触发立即执行)</li>
+											<li>定时任务显示下一个执行周期</li>
+											<li>支持前端任意日期格式处理</li>
+											<li>上传头像删除多余提交按钮</li>
+											<li>表格增加行间隔色配置项</li>
+											<li>表格增加转义HTML字符串配置项</li>
+											<li>表格增加显示/隐藏指定列</li>
+											<li>代码生成优化</li>
+											<li>操作日志参数格式化显示</li>
+											<li>页签新增新增全屏显示</li>
+											<li>新增一键打包部署</li>
+											<li>Excel注解新增多个参数</li>
+											<li>新增提交静默更新表格方法</li>
+											<li>新增服务监控菜单</li>
+										</ol>
+									</div>
+								</div>
+							</div>
 							<div class="panel panel-default">
 								<div class="panel-heading">
 								   <h5 class="panel-title">
 									   <a data-toggle="collapse" data-parent="#version" href="#v30">v3.0.0</a><code class="pull-right">2018.10.08</code>
 								   </h5>
 								</div>
-								<div id="v30" class="panel-collapse collapse in">
+								<div id="v30" class="panel-collapse collapse">
 									<div class="panel-body">
 									   <ol>
 											<li>升级poi到最新版3.17</li>

+ 2 - 2
ruoyi-admin/src/main/resources/templates/monitor/job/add.html

@@ -38,8 +38,8 @@
 			<div class="form-group">
 				<label class="col-sm-3 control-label">执行策略:</label>
 				<div class="col-sm-8">
-					<label class="radio-box"> <input type="radio" name="misfirePolicy" value="1" th:checked="true"/> 继续执行 </label> 
-					<label class="radio-box"> <input type="radio" name="misfirePolicy" value="2" /> 一次执行 </label> 
+					<label class="radio-box"> <input type="radio" name="misfirePolicy" value="1" th:checked="true"/> 立即执行 </label> 
+					<label class="radio-box"> <input type="radio" name="misfirePolicy" value="2" /> 执行一次 </label> 
 					<label class="radio-box"> <input type="radio" name="misfirePolicy" value="3" /> 放弃执行 </label>
 				</div>
 			</div>

+ 56 - 10
ruoyi-admin/src/main/resources/templates/monitor/job/detail.html

@@ -5,44 +5,90 @@
 <head th:include="include :: header"></head>
 <body class="white-bg">
 	<div class="wrapper wrapper-content animated fadeInRight ibox-content">
-	<form class="form-horizontal m-t" id="signupForm">
+	
+	<form class="form-horizontal m-t" id="jobLogForm" th:if="${name == 'jobLog'}">
 	    <div class="form-group">
-			<label class="col-sm-2 control-label">日志序号:</label>
+			<label class="col-sm-3 control-label">日志序号:</label>
 			<div class="form-control-static" th:text="${jobLog.jobLogId}">
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="col-sm-2 control-label">任务名称:</label>
+			<label class="col-sm-3 control-label">任务名称:</label>
 			<div class="form-control-static" th:text="${jobLog.jobName}">
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="col-sm-2 control-label">任务组名:</label>
+			<label class="col-sm-3 control-label">任务组名:</label>
 			<div class="form-control-static" th:text="${jobLog.jobGroup}">
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="col-sm-2 control-label">任务方法:</label>
-			<div class="form-control-static" th:text="${jobLog.methodName} + '(' + ${jobLog.methodParams} + ')'">
+			<label class="col-sm-3 control-label">任务方法:</label>
+			<div class="form-control-static" th:text="${jobLog.methodName} + '(' + ${#strings.defaultString(jobLog.methodParams,'')} + ')'">
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="col-sm-2 control-label">日志信息:</label>
+			<label class="col-sm-3 control-label">日志信息:</label>
 			<div class="form-control-static" th:text="${jobLog.jobMessage}">
 			</div>
 		</div>
 		<div class="form-group">
-			<label class="col-sm-2 control-label">执行状态:</label>
+			<label class="col-sm-3 control-label">执行状态:</label>
 			<div class="form-control-static" th:class="${jobLog.status == '0' ? 'label label-primary' : 'label label-danger'}" th:text="${jobLog.status == '0' ? '正常' : '失败'}">
 			</div>
 		</div>
 		<div class="form-group" th:style="'display:' + ${jobLog.status == '0' ? 'none' : 'block'}">
-			<label class="col-sm-2 control-label">异常信息:</label>
+			<label class="col-sm-3 control-label">异常信息:</label>
 			<div class="form-control-static" th:text="${jobLog.exceptionInfo}">
 			</div>
 		</div>
 	</form>
+	
+	<form class="form-horizontal m-t" id="jobForm" th:if="${name == 'job'}">
+	    <div class="form-group">
+			<label class="col-sm-3 control-label">任务序号:</label>
+			<div class="form-control-static" th:text="${job.jobId}">
+			</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">任务名称:</label>
+			<div class="form-control-static" th:text="${job.jobName}">
+			</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">任务组名:</label>
+			<div class="form-control-static" th:text="${job.jobGroup}">
+			</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">任务方法:</label>
+			<div class="form-control-static" th:text="${job.methodName} + '(' + ${#strings.defaultString(job.methodParams,'')} + ')'">
+			</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">执行表达式:</label>
+			<div class="form-control-static" th:text="${job.cronExpression}">
+			</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">下次执行时间:</label>
+			<div class="form-control-static" th:text="${#dates.format(job.nextValidTime, 'yyyy-MM-dd HH:mm:ss')}">
+			</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">执行策略:</label>
+			<div class="form-control-static" th:if="${job.misfirePolicy == '0'}">默认策略</div>
+			<div class="form-control-static" th:if="${job.misfirePolicy == '1'}">立即执行</div>
+			<div class="form-control-static" th:if="${job.misfirePolicy == '2'}">执行一次</div>
+			<div class="form-control-static" th:if="${job.misfirePolicy == '3'}">放弃执行</div>
+		</div>
+		<div class="form-group">
+			<label class="col-sm-3 control-label">执行状态:</label>
+			<div class="form-control-static" th:class="${job.status == '0' ? 'label label-primary' : 'label label-danger'}" th:text="${job.status == '0' ? '正常' : '暂停'}">
+			</div>
+		</div>
+	</form>
+	
     </div>
-    <div th:include="include :: footer"></div>
 </body>
 </html>

+ 2 - 2
ruoyi-admin/src/main/resources/templates/monitor/job/edit.html

@@ -39,8 +39,8 @@
 			<div class="form-group">
 				<label class="col-sm-3 control-label">执行策略:</label>
 				<div class="col-sm-8">
-					<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="1" /> 继续执行 </label> 
-					<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="2" /> 一次执行 </label> 
+					<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="1" /> 立即执行 </label> 
+					<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="2" /> 执行一次 </label> 
 					<label class="radio-box"> <input type="radio" th:field="*{misfirePolicy}" name="misfirePolicy" value="3" /> 放弃执行 </label>
 				</div>
 			</div>

+ 7 - 6
ruoyi-admin/src/main/resources/templates/monitor/job/job.html

@@ -42,12 +42,12 @@
 				<a class="btn btn-danger btn-del disabled" onclick="$.operate.removeAll()" shiro:hasPermission="monitor:job:remove">
 		            <i class="fa fa-remove"></i> 删除
 		        </a>
-		        <a class="btn btn-success" onclick="javascript:jobLog()" shiro:hasPermission="monitor:job:list">
-		            <i class="fa fa-list"></i> 日志
-		        </a>
 		         <a class="btn btn-warning" onclick="$.table.exportExcel()" shiro:hasPermission="monitor:job:export">
 		            <i class="fa fa-download"></i> 导出
 		        </a>
+		        <a class="btn btn-info" onclick="javascript:jobLog()" shiro:hasPermission="monitor:job:list">
+		            <i class="fa fa-list"></i> 日志
+		        </a>
 	        </div>
         
 	        <div class="col-sm-12 select-table table-striped">
@@ -57,6 +57,7 @@
 	</div>
 	<div th:include="include :: footer"></div>
 	<script th:inline="javascript">
+        var detailFlag = [[${@permission.hasPermi('monitor:job:detail')}]];
 		var editFlag = [[${@permission.hasPermi('monitor:job:edit')}]];
 		var removeFlag = [[${@permission.hasPermi('monitor:job:remove')}]];
 		var statusFlag = [[${@permission.hasPermi('monitor:job:changeStatus')}]];
@@ -66,6 +67,7 @@
 		$(function() {
 		    var options = {
 		        url: prefix + "/list",
+		        detailUrl: prefix + "/detail/{id}",
 		        createUrl: prefix + "/add",
 		        updateUrl: prefix + "/edit/{id}",
 		        removeUrl: prefix + "/remove",
@@ -124,8 +126,7 @@
 		                var actions = [];
 		                actions.push(statusTools(row));
 		                actions.push('<a class="btn btn-primary btn-xs ' + statusFlag + '" href="#" onclick="run(\'' + row.jobId + '\')"><i class="fa fa-play-circle-o"></i> 执行</a> ');
-		                actions.push('<a class="btn btn-success btn-xs ' + editFlag + '" href="#" onclick="$.operate.edit(\'' + row.jobId + '\')"><i class="fa fa-edit"></i>编辑</a> ');
-		                actions.push('<a class="btn btn-danger btn-xs ' + removeFlag + '" href="#" onclick="$.operate.remove(\'' + row.jobId + '\')"><i class="fa fa-remove"></i>删除</a>');
+		                actions.push('<a class="btn btn-warning btn-xs ' + detailFlag + '" href="#" onclick="$.operate.detail(\'' + row.jobId + '\')"><i class="fa fa-search"></i>详细</a> ');
 		                return actions.join('');
 		            }
 		        }]
@@ -137,7 +138,7 @@
 		    if (row.status == 1) {
 		        return '<a class="btn btn-info btn-xs ' + statusFlag + '" href="#" onclick="start(\'' + row.jobId + '\')"><i class="fa fa-play"></i>启用</a> ';
 		    } else {
-		    	return '<a class="btn btn-warning btn-xs ' + statusFlag + '" href="#" onclick="stop(\'' + row.jobId + '\')"><i class="fa fa-pause"></i>暂停</a> ';
+		    	return '<a class="btn btn-danger btn-xs ' + statusFlag + '" href="#" onclick="stop(\'' + row.jobId + '\')"><i class="fa fa-pause"></i>暂停</a> ';
 		    }
 		}
 		

+ 1 - 0
ruoyi-admin/src/main/resources/templates/monitor/logininfor/logininfor.html

@@ -72,6 +72,7 @@
 		        modalName: "登录日志",
 		        search: false,
 		        showExport: false,
+		        escape: true,
 		        columns: [{
 		            checkbox: true
 		        },

+ 1 - 0
ruoyi-admin/src/main/resources/templates/monitor/online/online.html

@@ -49,6 +49,7 @@
 		        sortName: "lastAccessTime",
 		        sortOrder: "desc",
 		        search: false,
+		        escape: true,
 		        columns: [{
 		            checkbox: true
 		        },

+ 1 - 0
ruoyi-admin/src/main/resources/templates/monitor/operlog/operlog.html

@@ -74,6 +74,7 @@
 		        modalName: "操作日志",
 		        search: false,
 		        showExport: false,
+		        escape: true,
 		        columns: [{
 		            checkbox: true
 		        },

+ 254 - 0
ruoyi-admin/src/main/resources/templates/monitor/server/server.html

@@ -0,0 +1,254 @@
+<!DOCTYPE html>
+<html lang="zh" xmlns:th="http://www.thymeleaf.org"
+	xmlns:shiro="http://www.pollix.at/thymeleaf/shiro">
+<meta charset="utf-8">
+<head th:include="include :: header"></head>
+<body class="gray-bg" id="test">
+    <div class="wrapper wrapper-content">
+        <div class="col-sm-12">
+            <div class="row">
+                <div class="col-sm-6">
+                    <div class="ibox float-e-margins">
+                        <div class="ibox-title">
+                            <h5>CPU</h5>
+                            <div class="ibox-tools">
+                                <a class="collapse-link"><i class="fa fa-chevron-up"></i>
+                                </a>
+                                <a class="close-link"><i class="fa fa-times"></i></a>
+                            </div>
+                        </div>
+                        <div class="ibox-content">
+                            <table class="table table-hover no-margins">
+                                <thead>
+                                    <tr>
+                                        <th>属性</th>
+                                        <th>值</th>
+                                    </tr>
+                                </thead>
+                                <tbody>
+                                    <tr>
+                                        <td>核心数</td>
+                                        <td th:text="${server.cpu.cpuNum}">0个</td>
+                                    </tr>
+                                    <tr>
+                                        <td>用户使用率</td>
+                                        <td th:text="${server.cpu.used + '%'}">0%</td>
+                                    </tr>
+                                    <tr>
+                                        <td>系统使用率</td>
+                                        <td th:text="${server.cpu.sys + '%'}">0%</td>
+                                    </tr>
+                                    <tr>
+                                        <td>当前空闲率</td>
+                                        <td th:text="${server.cpu.free + '%'}">0%</td>
+                                    </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+                
+                <div class="col-sm-6">
+                    <div class="ibox float-e-margins">
+                        <div class="ibox-title">
+                            <h5>内存</h5>
+                            <div class="ibox-tools">
+                                <a class="collapse-link"><i class="fa fa-chevron-up"></i></a>
+                                <a class="close-link"><i class="fa fa-times"></i></a>
+                            </div>
+                        </div>
+                        <div class="ibox-content">
+                            <table class="table table-hover no-margins">
+                                <thead>
+                                    <tr>
+                                        <th>属性</th>
+                                        <th>内存</th>
+                                        <th>JVM</th>
+                                    </tr>
+                                </thead>
+                                <tbody>
+                                    <tr>
+                                        <td>总内存</td>
+                                        <td th:text="${server.mem.total + 'G'}">0GB</td>
+                                        <td th:text="${server.jvm.total + 'M'}">0MB</td>
+                                    </tr>
+                                    <tr>
+                                        <td>已用内存</td>
+                                        <td th:text="${server.mem.used + 'G'}">0GB</td>
+                                        <td th:text="${server.jvm.used + 'M'}">0MB</td>
+                                    </tr>
+                                    <tr>
+                                        <td>剩余内存</td>
+                                        <td th:text="${server.mem.free + 'G'}">0GB</td>
+                                        <td th:text="${server.jvm.free + 'M'}">0MB</td>
+                                    </tr>
+                                    <tr>
+                                        <td>使用率</td>
+                                        <td th:class="${server.mem.usage gt 80} ? 'text-danger'">[[${server.mem.usage}]]%</td>
+                                        <td th:class="${server.jvm.usage gt 80} ? 'text-danger'">[[${server.jvm.usage}]]%</td>
+                                    </tr>
+                                </tbody>
+                            </table>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            
+            <div class="row">
+                <div class="col-sm-12">
+                    <div class="ibox float-e-margins">
+                        <div class="ibox-title">
+                            <h5>服务器信息</h5>
+                            <div class="ibox-tools">
+                                <a class="collapse-link">
+                                    <i class="fa fa-chevron-up"></i>
+                                </a>
+                                <a class="close-link">
+                                    <i class="fa fa-times"></i>
+                                </a>
+                            </div>
+                        </div>
+                        <div class="ibox-content">
+                            <div class="row">
+                                <div class="col-sm-12">
+                                    <table class="table table-hover margin bottom">
+                                        <tbody>
+                                            <tr>
+                                                <td>服务器名称</td>
+                                                <td th:text="${server.sys.computerName}">RuoYi</td>
+                                                <td>操作系统</td>
+                                                <td th:text="${server.sys.osName}">Linux</td>
+                                            </tr>
+                                            <tr>
+                                                <td>服务器IP</td>
+                                                <td th:text="${server.sys.computerIp}">127.0.0.1</td>
+                                                <td>系统架构</td>
+                                                <td th:text="${server.sys.osArch}">amd64</td>
+                                            </tr>
+                                        </tbody>
+                                    </table>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            
+            <div class="row">
+                <div class="col-sm-12">
+                    <div class="ibox float-e-margins">
+                        <div class="ibox-title">
+                            <h5>Java虚拟机信息</h5>
+                            <div class="ibox-tools">
+                                <a class="collapse-link">
+                                    <i class="fa fa-chevron-up"></i>
+                                </a>
+                                <a class="close-link">
+                                    <i class="fa fa-times"></i>
+                                </a>
+                            </div>
+                        </div>
+                        <div class="ibox-content">
+
+                            <div class="row">
+                                <div class="col-sm-12">
+                                    <table class="table table-hover margin bottom">
+                                        <tbody>
+                                            <tr>
+                                                <td>Java名称</td>
+                                                <td th:text="${server.jvm.name}">Java</td>
+                                                <td>Java版本</td>
+                                                <td th:text="${server.jvm.version}">1.8.0</td>
+                                            </tr>
+                                            <tr>
+                                                <td>启动时间</td>
+                                                <td th:text="${server.jvm.startTime}">2018-12-31 00:00:00</td>
+                                                <td>运行时长</td>
+                                                <td th:text="${server.jvm.runTime}">0天0时0分0秒</td>
+                                            </tr>
+                                            <tr>
+                                                <td colspan="1">安装路径</td>
+                                                <td colspan="3" th:text="${server.jvm.home}"></td>
+                                            </tr>
+                                             <tr>
+                                                <td colspan="1">项目路径</td>
+                                                <td colspan="3" th:text="${server.sys.userDir}"></td>
+                                            </tr>
+                                        </tbody>
+                                    </table>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+            
+            <div class="row">
+                <div class="col-sm-12">
+                    <div class="ibox float-e-margins">
+                        <div class="ibox-title">
+                            <h5>磁盘状态</h5>
+                            <div class="ibox-tools">
+                                <a class="collapse-link">
+                                    <i class="fa fa-chevron-up"></i>
+                                </a>
+                                <a class="close-link">
+                                    <i class="fa fa-times"></i>
+                                </a>
+                            </div>
+                        </div>
+                        <div class="ibox-content">
+
+                            <div class="row">
+                                <div class="col-sm-12">
+                                    <table class="table table-hover margin bottom">
+                                        <thead>
+                                            <tr>
+                                                <th>盘符路径</th>
+                                                <th>文件系统</th>
+                                                <th>盘符类型</th>
+                                                <th>总大小</th>
+                                                <th>可用大小</th>
+                                                <th>已用大小</th>
+                                                <th>已用百分比</th>
+                                            </tr>
+                                        </thead>
+                                        <tbody>
+                                            <tr th:each="sysFile : ${server.sysFiles}">
+                                                <td th:text="${sysFile.dirName}">C:\</td>
+                                                <td th:text="${sysFile.sysTypeName}">NTFS</td>
+                                                <td th:text="${sysFile.typeName}">local</td>
+                                                <td th:text="${sysFile.total}">0GB</td>
+                                                <td th:text="${sysFile.free}">0GB</td>
+                                                <td th:text="${sysFile.used}">0GB</td>
+                                                <td th:class="${sysFile.usage gt 80} ? 'text-danger'">[[${sysFile.usage}]]%</td>
+                                            </tr>
+                                        </tbody>
+                                    </table>
+                                </div>
+                            </div>
+                        </div>
+                    </div>
+                </div>
+            </div>
+        </div>
+    </div>
+</body>
+<div th:include="include :: footer"></div>
+<script>
+    $(".modal").appendTo("body"), $("[data-toggle=popover]").popover(), $(".collapse-link").click(function() {
+        var div_ibox = $(this).closest("div.ibox"),
+        e = $(this).find("i"),
+        i = div_ibox.find("div.ibox-content");
+        i.slideToggle(200),
+        e.toggleClass("fa-chevron-up").toggleClass("fa-chevron-down"),
+        div_ibox.toggleClass("").toggleClass("border-bottom"),
+        setTimeout(function() {
+        	div_ibox.resize();
+        }, 50);
+    }), $(".close-link").click(function () {
+		var div_ibox = $(this).closest("div.ibox");
+		div_ibox.remove()
+	});
+</script>
+</html>

+ 1 - 1
ruoyi-common/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>ruoyi</artifactId>
         <groupId>com.ruoyi</groupId>
-        <version>3.0</version>
+        <version>3.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 	

+ 109 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/Arith.java

@@ -0,0 +1,109 @@
+package com.ruoyi.common.utils;
+
+import java.math.BigDecimal;
+
+/**
+ * 精确的浮点数运算
+ * 
+ * @author ruoyi
+ */
+public class Arith
+{
+
+    // 默认除法运算精度
+    private static final int DEF_DIV_SCALE = 10;
+
+    // 这个类不能实例化
+    private Arith()
+    {
+    }
+
+    /**
+     * 提供精确的加法运算。
+     * @param v1 被加数
+     * @param v2 加数
+     * @return 两个参数的和
+     */
+    public static double add(double v1, double v2)
+    {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.add(b2).doubleValue();
+    }
+
+    /**
+     * 提供精确的减法运算。
+     * @param v1 被减数
+     * @param v2 减数
+     * @return 两个参数的差
+     */
+    public static double sub(double v1, double v2)
+    {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.subtract(b2).doubleValue();
+    }
+
+    /**
+     * 提供精确的乘法运算。
+     * @param v1 被乘数
+     * @param v2 乘数
+     * @return 两个参数的积
+     */
+    public static double mul(double v1, double v2)
+    {
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.multiply(b2).doubleValue();
+    }
+
+    /**
+     * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到
+     * 小数点以后10位,以后的数字四舍五入。
+     * @param v1 被除数
+     * @param v2 除数
+     * @return 两个参数的商
+     */
+    public static double div(double v1, double v2)
+    {
+        return div(v1, v2, DEF_DIV_SCALE);
+    }
+
+    /**
+     * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指
+     * 定精度,以后的数字四舍五入。
+     * @param v1 被除数
+     * @param v2 除数
+     * @param scale 表示表示需要精确到小数点以后几位。
+     * @return 两个参数的商
+     */
+    public static double div(double v1, double v2, int scale)
+    {
+        if (scale < 0)
+        {
+            throw new IllegalArgumentException(
+                    "The scale must be a positive integer or zero");
+        }
+        BigDecimal b1 = new BigDecimal(Double.toString(v1));
+        BigDecimal b2 = new BigDecimal(Double.toString(v2));
+        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+
+    /**
+     * 提供精确的小数位四舍五入处理。
+     * @param v 需要四舍五入的数字
+     * @param scale 小数点后保留几位
+     * @return 四舍五入后的结果
+     */
+    public static double round(double v, int scale)
+    {
+        if (scale < 0)
+        {
+            throw new IllegalArgumentException(
+                    "The scale must be a positive integer or zero");
+        }
+        BigDecimal b = new BigDecimal(Double.toString(v));
+        BigDecimal one = new BigDecimal("1");
+        return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
+    }
+}

+ 32 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java

@@ -1,5 +1,6 @@
 package com.ruoyi.common.utils;
 
+import java.lang.management.ManagementFactory;
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.Date;
@@ -120,4 +121,35 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
             return null;
         }
     }
+    
+    /**
+     * 获取服务器启动时间
+     */
+    public static Date getServerStartDate()
+    {
+        long time = ManagementFactory.getRuntimeMXBean().getStartTime();
+        return new Date(time);
+    }
+
+    /**
+     * 计算两个时间差
+     */
+    public static String getDatePoor(Date endDate, Date nowDate)
+    {
+        long nd = 1000 * 24 * 60 * 60;
+        long nh = 1000 * 60 * 60;
+        long nm = 1000 * 60;
+        // long ns = 1000;
+        // 获得两个时间的毫秒时间差异
+        long diff = endDate.getTime() - nowDate.getTime();
+        // 计算差多少天
+        long day = diff / nd;
+        // 计算差多少小时
+        long hour = diff % nd / nh;
+        // 计算差多少分钟
+        long min = diff % nd % nh / nm;
+        // 计算差多少秒//输出结果
+        // long sec = diff % nd % nh % nm / ns;
+        return day + "天" + hour + "小时" + min + "分钟";
+    }
 }

+ 26 - 0
ruoyi-common/src/main/java/com/ruoyi/common/utils/IpUtils.java

@@ -1,5 +1,7 @@
 package com.ruoyi.common.utils;
 
+import java.net.InetAddress;
+import java.net.UnknownHostException;
 import javax.servlet.http.HttpServletRequest;
 
 /**
@@ -155,4 +157,28 @@ public class IpUtils
         }
         return bytes;
     }
+
+    public static String getHostIp()
+    {
+        try
+        {
+            return InetAddress.getLocalHost().getHostAddress();
+        }
+        catch (UnknownHostException e)
+        {
+        }
+        return "127.0.0.1";
+    }
+
+    public static String getHostName()
+    {
+        try
+        {
+            return InetAddress.getLocalHost().getHostName();
+        }
+        catch (UnknownHostException e)
+        {
+        }
+        return "未知";
+    }
 }

+ 19 - 3
ruoyi-framework/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>ruoyi</artifactId>
         <groupId>com.ruoyi</groupId>
-        <version>3.0</version>
+        <version>3.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 	
@@ -110,14 +110,30 @@
             <artifactId>ruoyi-generator</artifactId>
             <version>${ruoyi.version}</version>
         </dependency>
-
-
+        
 		<!-- pagehelper 分页插件 -->
 		<dependency>
 			<groupId>com.github.pagehelper</groupId>
 			<artifactId>pagehelper-spring-boot-starter</artifactId>
 			<version>${pagehelper.boot.version}</version>
 		</dependency>
+		
+		<!-- 获取系统信息 -->
+		<dependency>
+			<groupId>com.github.oshi</groupId>
+			<artifactId>oshi-core</artifactId>
+			<version>${oshi.version}</version>
+		</dependency>
+		
+		<dependency>
+			<groupId>net.java.dev.jna</groupId>
+			<artifactId>jna</artifactId>
+		</dependency>
+		
+		<dependency>
+			<groupId>net.java.dev.jna</groupId>
+			<artifactId>jna-platform</artifactId>
+		</dependency>
 
     </dependencies>
     

+ 1 - 6
ruoyi-framework/src/main/java/com/ruoyi/framework/shiro/web/filter/sync/SyncOnlineSessionFilter.java

@@ -20,14 +20,9 @@ public class SyncOnlineSessionFilter extends PathMatchingFilter
 
     /**
      * 同步会话数据到DB 一次请求最多同步一次 防止过多处理 需要放到Shiro过滤器之前
-     *
-     * @param request
-     * @param response
-     * @return
-     * @throws Exception
      */
     @Override
-    protected boolean preHandle(ServletRequest request, ServletResponse response) throws Exception
+    protected boolean onPreHandle(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception
     {
         OnlineSession session = (OnlineSession) request.getAttribute(ShiroConstants.ONLINE_SESSION);
         // 如果session stop了 也不同步

+ 238 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/Server.java

@@ -0,0 +1,238 @@
+package com.ruoyi.framework.web.domain;
+
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Properties;
+import com.ruoyi.common.utils.Arith;
+import com.ruoyi.common.utils.IpUtils;
+import com.ruoyi.framework.web.domain.server.Cpu;
+import com.ruoyi.framework.web.domain.server.Jvm;
+import com.ruoyi.framework.web.domain.server.Mem;
+import com.ruoyi.framework.web.domain.server.Sys;
+import com.ruoyi.framework.web.domain.server.SysFile;
+import oshi.SystemInfo;
+import oshi.hardware.CentralProcessor;
+import oshi.hardware.CentralProcessor.TickType;
+import oshi.hardware.GlobalMemory;
+import oshi.hardware.HardwareAbstractionLayer;
+import oshi.software.os.FileSystem;
+import oshi.software.os.OSFileStore;
+import oshi.software.os.OperatingSystem;
+import oshi.util.Util;
+
+/**
+ * 服务器相关信息
+ * 
+ * @author ruoyi
+ */
+public class Server
+{
+    /**
+     * CPU相关信息
+     */
+    private Cpu cpu = new Cpu();
+
+    /**
+     * 內存相关信息
+     */
+    private Mem mem = new Mem();
+
+    /**
+     * JVM相关信息
+     */
+    private Jvm jvm = new Jvm();
+
+    /**
+     * 服务器相关信息
+     */
+    private Sys sys = new Sys();
+
+    /**
+     * 磁盘相关信息
+     */
+    private List<SysFile> sysFiles = new LinkedList<SysFile>();
+
+    public Cpu getCpu()
+    {
+        return cpu;
+    }
+
+    public void setCpu(Cpu cpu)
+    {
+        this.cpu = cpu;
+    }
+
+    public Mem getMem()
+    {
+        return mem;
+    }
+
+    public void setMem(Mem mem)
+    {
+        this.mem = mem;
+    }
+
+    public Jvm getJvm()
+    {
+        return jvm;
+    }
+
+    public void setJvm(Jvm jvm)
+    {
+        this.jvm = jvm;
+    }
+
+    public Sys getSys()
+    {
+        return sys;
+    }
+
+    public void setSys(Sys sys)
+    {
+        this.sys = sys;
+    }
+
+    public List<SysFile> getSysFiles()
+    {
+        return sysFiles;
+    }
+
+    public void setSysFiles(List<SysFile> sysFiles)
+    {
+        this.sysFiles = sysFiles;
+    }
+
+    public void copyTo() throws Exception
+    {
+        SystemInfo si = new SystemInfo();
+        HardwareAbstractionLayer hal = si.getHardware();
+
+        setCpuInfo(hal.getProcessor());
+
+        setMemInfo(hal.getMemory());
+
+        setSysInfo();
+
+        setJvmInfo();
+
+        setSysFiles(si.getOperatingSystem());
+    }
+
+    /**
+     * 设置CPU信息
+     */
+    private void setCpuInfo(CentralProcessor processor)
+    {
+        // CPU信息
+        long[] prevTicks = processor.getSystemCpuLoadTicks();
+        Util.sleep(500);
+        long[] ticks = processor.getSystemCpuLoadTicks();
+        long nice = ticks[TickType.NICE.getIndex()] - prevTicks[TickType.NICE.getIndex()];
+        long irq = ticks[TickType.IRQ.getIndex()] - prevTicks[TickType.IRQ.getIndex()];
+        long softirq = ticks[TickType.SOFTIRQ.getIndex()] - prevTicks[TickType.SOFTIRQ.getIndex()];
+        long steal = ticks[TickType.STEAL.getIndex()] - prevTicks[TickType.STEAL.getIndex()];
+        long cSys = ticks[TickType.SYSTEM.getIndex()] - prevTicks[TickType.SYSTEM.getIndex()];
+        long user = ticks[TickType.USER.getIndex()] - prevTicks[TickType.USER.getIndex()];
+        long iowait = ticks[TickType.IOWAIT.getIndex()] - prevTicks[TickType.IOWAIT.getIndex()];
+        long idle = ticks[TickType.IDLE.getIndex()] - prevTicks[TickType.IDLE.getIndex()];
+        long totalCpu = user + nice + cSys + idle + iowait + irq + softirq + steal;
+        cpu.setCpuNum(processor.getLogicalProcessorCount());
+        cpu.setTotal(totalCpu);
+        cpu.setSys(cSys);
+        cpu.setUsed(user);
+        cpu.setWait(iowait);
+        cpu.setFree(idle);
+    }
+
+    /**
+     * 设置内存信息
+     */
+    private void setMemInfo(GlobalMemory memory)
+    {
+        mem.setTotal(memory.getTotal());
+        mem.setUsed(memory.getTotal() - memory.getAvailable());
+        mem.setFree(memory.getAvailable());
+    }
+
+    /**
+     * 设置服务器信息
+     */
+    private void setSysInfo()
+    {
+        Properties props = System.getProperties();
+        sys.setComputerName(IpUtils.getHostName());
+        sys.setComputerIp(IpUtils.getHostIp());
+        sys.setOsName(props.getProperty("os.name"));
+        sys.setOsArch(props.getProperty("os.arch"));
+        sys.setUserDir(props.getProperty("user.dir"));
+    }
+
+    /**
+     * 设置Java虚拟机
+     */
+    private void setJvmInfo() throws UnknownHostException
+    {
+        Properties props = System.getProperties();
+        jvm.setTotal(Runtime.getRuntime().totalMemory());
+        jvm.setMax(Runtime.getRuntime().maxMemory());
+        jvm.setFree(Runtime.getRuntime().freeMemory());
+        jvm.setVersion(props.getProperty("java.version"));
+        jvm.setHome(props.getProperty("java.home"));
+    }
+
+    /**
+     * 设置磁盘信息
+     */
+    private void setSysFiles(OperatingSystem os)
+    {
+        FileSystem fileSystem = os.getFileSystem();
+        OSFileStore[] fsArray = fileSystem.getFileStores();
+        for (OSFileStore fs : fsArray)
+        {
+            long free = fs.getUsableSpace();
+            long total = fs.getTotalSpace();
+            long used = total - free;
+            SysFile sysFile = new SysFile();
+            sysFile.setDirName(fs.getMount());
+            sysFile.setSysTypeName(fs.getType());
+            sysFile.setTypeName(fs.getName());
+            sysFile.setTotal(convertFileSize(total));
+            sysFile.setFree(convertFileSize(free));
+            sysFile.setUsed(convertFileSize(used));
+            sysFile.setUsage(Arith.mul(Arith.div(used, total, 4), 100));
+            sysFiles.add(sysFile);
+        }
+    }
+
+    /**
+     * 字节转换
+     * 
+     * @param size 字节大小
+     * @return 转换后值
+     */
+    public String convertFileSize(long size)
+    {
+        long kb = 1024;
+        long mb = kb * 1024;
+        long gb = mb * 1024;
+        if (size >= gb)
+        {
+            return String.format("%.1f GB", (float) size / gb);
+        }
+        else if (size >= mb)
+        {
+            float f = (float) size / mb;
+            return String.format(f > 100 ? "%.0f MB" : "%.1f MB", f);
+        }
+        else if (size >= kb)
+        {
+            float f = (float) size / kb;
+            return String.format(f > 100 ? "%.0f KB" : "%.1f KB", f);
+        }
+        else
+        {
+            return String.format("%d B", size);
+        }
+    }
+}

+ 101 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Cpu.java

@@ -0,0 +1,101 @@
+package com.ruoyi.framework.web.domain.server;
+
+import com.ruoyi.common.utils.Arith;
+
+/**
+ * CPU相关信息
+ * 
+ * @author ruoyi
+ */
+public class Cpu
+{
+    /**
+     * 核心数
+     */
+    private int cpuNum;
+
+    /**
+     * CPU总的使用率
+     */
+    private double total;
+
+    /**
+     * CPU系统使用率
+     */
+    private double sys;
+
+    /**
+     * CPU用户使用率
+     */
+    private double used;
+
+    /**
+     * CPU当前等待率
+     */
+    private double wait;
+
+    /**
+     * CPU当前空闲率
+     */
+    private double free;
+
+    public int getCpuNum()
+    {
+        return cpuNum;
+    }
+
+    public void setCpuNum(int cpuNum)
+    {
+        this.cpuNum = cpuNum;
+    }
+
+    public double getTotal()
+    {
+        return Arith.round(Arith.mul(total, 100), 2);
+    }
+
+    public void setTotal(double total)
+    {
+        this.total = total;
+    }
+
+    public double getSys()
+    {
+        return Arith.round(Arith.mul(sys / total, 100), 2);
+    }
+
+    public void setSys(double sys)
+    {
+        this.sys = sys;
+    }
+
+    public double getUsed()
+    {
+        return Arith.round(Arith.mul(used / total, 100), 2);
+    }
+
+    public void setUsed(double used)
+    {
+        this.used = used;
+    }
+
+    public double getWait()
+    {
+        return Arith.round(Arith.mul(wait / total, 100), 2);
+    }
+
+    public void setWait(double wait)
+    {
+        this.wait = wait;
+    }
+
+    public double getFree()
+    {
+        return Arith.round(Arith.mul(free / total, 100), 2);
+    }
+
+    public void setFree(double free)
+    {
+        this.free = free;
+    }
+}

+ 122 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Jvm.java

@@ -0,0 +1,122 @@
+package com.ruoyi.framework.web.domain.server;
+
+import java.lang.management.ManagementFactory;
+import com.ruoyi.common.utils.Arith;
+import com.ruoyi.common.utils.DateUtils;
+
+/**
+ * JVM相关信息
+ * 
+ * @author ruoyi
+ */
+public class Jvm
+{
+    /**
+     * 当前JVM占用的内存总数(M)
+     */
+    private double total;
+
+    /**
+     * JVM最大可用内存总数(M)
+     */
+    private double max;
+
+    /**
+     * JVM空闲内存(M)
+     */
+    private double free;
+
+    /**
+     * JDK版本
+     */
+    private String version;
+
+    /**
+     * JDK路径
+     */
+    private String home;
+
+    public double getTotal()
+    {
+        return Arith.div(total, (1024 * 1024), 2);
+    }
+
+    public void setTotal(double total)
+    {
+        this.total = total;
+    }
+
+    public double getMax()
+    {
+        return Arith.div(max, (1024 * 1024), 2);
+    }
+
+    public void setMax(double max)
+    {
+        this.max = max;
+    }
+
+    public double getFree()
+    {
+        return Arith.div(free, (1024 * 1024), 2);
+    }
+
+    public void setFree(double free)
+    {
+        this.free = free;
+    }
+
+    public double getUsed()
+    {
+        return Arith.div(total - free, (1024 * 1024), 2);
+    }
+
+    public double getUsage()
+    {
+        return Arith.mul(Arith.div(total - free, total, 4), 100);
+    }
+
+    /**
+     * 获取JDK名称
+     */
+    public String getName()
+    {
+        return ManagementFactory.getRuntimeMXBean().getVmName();
+    }
+
+    public String getVersion()
+    {
+        return version;
+    }
+
+    public void setVersion(String version)
+    {
+        this.version = version;
+    }
+
+    public String getHome()
+    {
+        return home;
+    }
+
+    public void setHome(String home)
+    {
+        this.home = home;
+    }
+
+    /**
+     * JDK启动时间
+     */
+    public String getStartTime()
+    {
+        return DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, DateUtils.getServerStartDate());
+    }
+
+    /**
+     * JDK运行时间
+     */
+    public String getRunTime()
+    {
+        return DateUtils.getDatePoor(DateUtils.getNowDate(), DateUtils.getServerStartDate());
+    }
+}

+ 61 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Mem.java

@@ -0,0 +1,61 @@
+package com.ruoyi.framework.web.domain.server;
+
+import com.ruoyi.common.utils.Arith;
+
+/**
+ * 內存相关信息
+ * 
+ * @author ruoyi
+ */
+public class Mem
+{
+    /**
+     * 内存总量
+     */
+    private double total;
+
+    /**
+     * 已用内存
+     */
+    private double used;
+
+    /**
+     * 剩余内存
+     */
+    private double free;
+
+    public double getTotal()
+    {
+        return Arith.div(total, (1024 * 1024 * 1024), 2);
+    }
+
+    public void setTotal(long total)
+    {
+        this.total = total;
+    }
+
+    public double getUsed()
+    {
+        return Arith.div(used, (1024 * 1024 * 1024), 2);
+    }
+
+    public void setUsed(long used)
+    {
+        this.used = used;
+    }
+
+    public double getFree()
+    {
+        return Arith.div(free, (1024 * 1024 * 1024), 2);
+    }
+
+    public void setFree(long free)
+    {
+        this.free = free;
+    }
+
+    public double getUsage()
+    {
+        return Arith.mul(Arith.div(used, total, 4), 100);
+    }
+}

+ 84 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/Sys.java

@@ -0,0 +1,84 @@
+package com.ruoyi.framework.web.domain.server;
+
+/**
+ * 系统相关信息
+ * 
+ * @author ruoyi
+ */
+public class Sys
+{
+    /**
+     * 服务器名称
+     */
+    private String computerName;
+
+    /**
+     * 服务器Ip
+     */
+    private String computerIp;
+
+    /**
+     * 项目路径
+     */
+    private String userDir;
+
+    /**
+     * 操作系统
+     */
+    private String osName;
+
+    /**
+     * 系统架构
+     */
+    private String osArch;
+
+    public String getComputerName()
+    {
+        return computerName;
+    }
+
+    public void setComputerName(String computerName)
+    {
+        this.computerName = computerName;
+    }
+
+    public String getComputerIp()
+    {
+        return computerIp;
+    }
+
+    public void setComputerIp(String computerIp)
+    {
+        this.computerIp = computerIp;
+    }
+
+    public String getUserDir()
+    {
+        return userDir;
+    }
+
+    public void setUserDir(String userDir)
+    {
+        this.userDir = userDir;
+    }
+
+    public String getOsName()
+    {
+        return osName;
+    }
+
+    public void setOsName(String osName)
+    {
+        this.osName = osName;
+    }
+
+    public String getOsArch()
+    {
+        return osArch;
+    }
+
+    public void setOsArch(String osArch)
+    {
+        this.osArch = osArch;
+    }
+}

+ 114 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/web/domain/server/SysFile.java

@@ -0,0 +1,114 @@
+package com.ruoyi.framework.web.domain.server;
+
+/**
+ * 系统文件相关信息
+ * 
+ * @author ruoyi
+ */
+public class SysFile
+{
+    /**
+     * 盘符路径
+     */
+    private String dirName;
+
+    /**
+     * 盘符类型
+     */
+    private String sysTypeName;
+
+    /**
+     * 文件类型
+     */
+    private String typeName;
+
+    /**
+     * 总大小
+     */
+    private String total;
+
+    /**
+     * 剩余大小
+     */
+    private String free;
+
+    /**
+     * 已经使用量
+     */
+    private String used;
+
+    /**
+     * 资源的使用率
+     */
+    private double usage;
+
+    public String getDirName()
+    {
+        return dirName;
+    }
+
+    public void setDirName(String dirName)
+    {
+        this.dirName = dirName;
+    }
+
+    public String getSysTypeName()
+    {
+        return sysTypeName;
+    }
+
+    public void setSysTypeName(String sysTypeName)
+    {
+        this.sysTypeName = sysTypeName;
+    }
+
+    public String getTypeName()
+    {
+        return typeName;
+    }
+
+    public void setTypeName(String typeName)
+    {
+        this.typeName = typeName;
+    }
+
+    public String getTotal()
+    {
+        return total;
+    }
+
+    public void setTotal(String total)
+    {
+        this.total = total;
+    }
+
+    public String getFree()
+    {
+        return free;
+    }
+
+    public void setFree(String free)
+    {
+        this.free = free;
+    }
+
+    public String getUsed()
+    {
+        return used;
+    }
+
+    public void setUsed(String used)
+    {
+        this.used = used;
+    }
+
+    public double getUsage()
+    {
+        return usage;
+    }
+
+    public void setUsage(double usage)
+    {
+        this.usage = usage;
+    }
+}

+ 1 - 1
ruoyi-generator/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>ruoyi</artifactId>
         <groupId>com.ruoyi</groupId>
-        <version>3.0</version>
+        <version>3.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 1 - 1
ruoyi-quartz/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>ruoyi</artifactId>
         <groupId>com.ruoyi</groupId>
-        <version>3.0</version>
+        <version>3.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
 

+ 14 - 1
ruoyi-quartz/src/main/java/com/ruoyi/quartz/domain/SysJob.java

@@ -1,11 +1,14 @@
 package com.ruoyi.quartz.domain;
 
+import java.io.Serializable;
+import java.util.Date;
 import org.apache.commons.lang3.builder.ToStringBuilder;
 import org.apache.commons.lang3.builder.ToStringStyle;
-import java.io.Serializable;
 import com.ruoyi.common.annotation.Excel;
 import com.ruoyi.common.base.BaseEntity;
 import com.ruoyi.common.constant.ScheduleConstants;
+import com.ruoyi.common.utils.StringUtils;
+import com.ruoyi.quartz.util.CronUtils;
 
 /**
  * 定时任务调度表 sys_job
@@ -108,6 +111,15 @@ public class SysJob extends BaseEntity implements Serializable
         this.cronExpression = cronExpression;
     }
 
+    public Date getNextValidTime()
+    {
+        if (StringUtils.isNotEmpty(cronExpression))
+        {
+            return CronUtils.getNextExecution(cronExpression);
+        }
+        return null;
+    }
+
     public String getMisfirePolicy()
     {
         return misfirePolicy;
@@ -137,6 +149,7 @@ public class SysJob extends BaseEntity implements Serializable
             .append("methodName", getMethodName())
             .append("methodParams", getMethodParams())
             .append("cronExpression", getCronExpression())
+            .append("nextValidTime", getNextValidTime())
             .append("misfirePolicy", getMisfirePolicy())
             .append("status", getStatus())
             .append("createBy", getCreateBy())

+ 2 - 0
ruoyi-quartz/src/main/java/com/ruoyi/quartz/util/ScheduleJob.java

@@ -4,6 +4,7 @@ import java.util.Date;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
+import org.quartz.DisallowConcurrentExecution;
 import org.quartz.JobExecutionContext;
 import org.quartz.JobExecutionException;
 import org.slf4j.Logger;
@@ -23,6 +24,7 @@ import com.ruoyi.quartz.service.ISysJobLogService;
  * @author ruoyi
  *
  */
+@DisallowConcurrentExecution
 public class ScheduleJob extends QuartzJobBean
 {
     private static final Logger log = LoggerFactory.getLogger(ScheduleJob.class);

+ 1 - 1
ruoyi-system/pom.xml

@@ -5,7 +5,7 @@
     <parent>
         <artifactId>ruoyi</artifactId>
         <groupId>com.ruoyi</groupId>
-        <version>3.0</version>
+        <version>3.1</version>
     </parent>
     <modelVersion>4.0.0</modelVersion>
     

Разница между файлами не показана из-за своего большого размера
+ 0 - 4851
sql/ruoyi.pdb


Разница между файлами не показана из-за своего большого размера
+ 621 - 519
sql/ry_20181124.sql