若依 3.1

This commit is contained in:
RuoYi
2018-12-01 16:14:19 +08:00
parent 451caf12fc
commit 6a592827e8
41 changed files with 2004 additions and 5547 deletions

View File

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

View File

@ -1,14 +0,0 @@
@echo off
echo.
echo [<5B><>Ϣ] ʹ<><CAB9> Spring Boot Tomcat <20><><EFBFBD><EFBFBD> Web <20><><EFBFBD>̡<EFBFBD>
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

View File

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

View File

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

View File

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

View File

@ -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";
}
/** /**
* 任务调度状态修改 * 任务调度状态修改
*/ */

View File

@ -74,6 +74,7 @@ public class SysJobLogController extends BaseController
@GetMapping("/detail/{jobLogId}") @GetMapping("/detail/{jobLogId}")
public String detail(@PathVariable("jobLogId") Long jobLogId, ModelMap mmap) public String detail(@PathVariable("jobLogId") Long jobLogId, ModelMap mmap)
{ {
mmap.put("name", "jobLog");
mmap.put("jobLog", jobLogService.selectJobLogById(jobLogId)); mmap.put("jobLog", jobLogService.selectJobLogById(jobLogId));
return prefix + "/detail"; return prefix + "/detail";
} }

View File

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

View File

@ -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) { function createMenuItem(dataUrl, menuName) {
dataIndex = $.common.random(1,100), dataIndex = $.common.random(1,100),
@ -154,6 +163,22 @@ function createMenuItem(dataUrl, menuName) {
return false; 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处理 */ /** 设置全局ajax处理 */
$.ajaxSetup({ $.ajaxSetup({
complete: function(XMLHttpRequest, textStatus) { complete: function(XMLHttpRequest, textStatus) {

View File

@ -17,6 +17,7 @@
_sortOrder = $.common.isEmpty(options.sortOrder) ? "asc" : options.sortOrder; _sortOrder = $.common.isEmpty(options.sortOrder) ? "asc" : options.sortOrder;
_sortName = $.common.isEmpty(options.sortName) ? "" : options.sortName; _sortName = $.common.isEmpty(options.sortName) ? "" : options.sortName;
_striped = $.common.isEmpty(options.striped) ? false : options.striped; _striped = $.common.isEmpty(options.striped) ? false : options.striped;
_escape = $.common.isEmpty(options.escape) ? false : options.escape;
$('#bootstrap-table').bootstrapTable({ $('#bootstrap-table').bootstrapTable({
url: options.url, // 请求后台的URL* url: options.url, // 请求后台的URL*
contentType: "application/x-www-form-urlencoded", // 编码类型 contentType: "application/x-www-form-urlencoded", // 编码类型
@ -31,6 +32,7 @@
pageNumber: 1, // 初始化加载第一页,默认第一页 pageNumber: 1, // 初始化加载第一页,默认第一页
pageSize: 10, // 每页的记录行数(* pageSize: 10, // 每页的记录行数(*
pageList: [10, 25, 50], // 可供选择的每页的行数(* pageList: [10, 25, 50], // 可供选择的每页的行数(*
escape: _escape, // 转义HTML字符串
iconSize: 'outline', // 图标大小undefined默认的按钮尺寸 xs超小按钮sm小按钮lg大按钮 iconSize: 'outline', // 图标大小undefined默认的按钮尺寸 xs超小按钮sm小按钮lg大按钮
toolbar: '#toolbar', // 指定工作栏 toolbar: '#toolbar', // 指定工作栏
sidePagination: "server", // 启用服务端分页 sidePagination: "server", // 启用服务端分页
@ -124,6 +126,14 @@
} }
}); });
return actions.join(''); 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) { random: function (min, max) {
return Math.floor((Math.random() * max) + min); 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)
} }
} }
}); });

View File

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

View File

@ -15,7 +15,7 @@
<link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/> <link th:href="@{/css/font-awesome.min.css}" rel="stylesheet"/>
<link th:href="@{/css/animate.css}" rel="stylesheet"/> <link th:href="@{/css/animate.css}" rel="stylesheet"/>
<link th:href="@{/css/style.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"> <style type="text/css">
.nav > li:hover .dropdown-menu {display: block;} .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; } #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="收起菜单"> <a class="navbar-minimalize minimalize-styl-2 btn btn-default " href="#" title="收起菜单">
<i class="fa fa-bars"></i> <i class="fa fa-bars"></i>
</a> </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> </div>
<ul class="nav navbar-top-links navbar-right welcome-message"> <ul class="nav navbar-top-links navbar-right welcome-message">
<li> <li>
@ -141,7 +136,7 @@
<script th:src="@{/js/plugins/slimscroll/jquery.slimscroll.min.js}"></script> <script th:src="@{/js/plugins/slimscroll/jquery.slimscroll.min.js}"></script>
<script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script> <script th:src="@{/ajax/libs/blockUI/jquery.blockUI.js}"></script>
<script src="http://tajs.qq.com/stats?sId=62048022"></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="@{/ruoyi/index.js}"></script>
<script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script> <script th:src="@{/ajax/libs/fullscreen/jquery.fullscreen.js}"></script>
</body> </body>

View File

@ -12,7 +12,7 @@
<link href="../static/css/style.css" th:href="@{css/style.css}" rel="stylesheet"/> <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/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/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]> <!--[if lt IE 9]>
<meta http-equiv="refresh" content="0;ie.html" /> <meta http-equiv="refresh" content="0;ie.html" />
<![endif]--> <![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/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="../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="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> <script src="../static/ruoyi/login.js" th:src="@{/ruoyi/login.js}"></script>
</body> </body>
</html> </html>

View File

@ -16,9 +16,9 @@
<div class="row border-bottom white-bg dashboard-header"> <div class="row border-bottom white-bg dashboard-header">
<div class="col-sm-12"> <div class="col-sm-12">
<blockquote class="text-warning" style="font-size:14px"> <blockquote class="text-warning" style="font-size:14px">
2018年度最受欢迎中国开源软件评选 领取阿里云1888通用代金券(新老客户均可用)
<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> <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">请给若依/RuoYi 投票,谢谢支持</h4> <h4 class="text-danger">云产品通用红包,可叠加官网常规优惠使用</h4>
</blockquote> </blockquote>
<hr> <hr>
@ -94,13 +94,43 @@
<div class="ibox-content no-padding"> <div class="ibox-content no-padding">
<div class="panel-body"> <div class="panel-body">
<div class="panel-group" id="version"> <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 panel-default">
<div class="panel-heading"> <div class="panel-heading">
<h5 class="panel-title"> <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> <a data-toggle="collapse" data-parent="#version" href="#v30">v3.0.0</a><code class="pull-right">2018.10.08</code>
</h5> </h5>
</div> </div>
<div id="v30" class="panel-collapse collapse in"> <div id="v30" class="panel-collapse collapse">
<div class="panel-body"> <div class="panel-body">
<ol> <ol>
<li>升级poi到最新版3.17</li> <li>升级poi到最新版3.17</li>

View File

@ -38,8 +38,8 @@
<div class="form-group"> <div class="form-group">
<label class="col-sm-3 control-label">执行策略:</label> <label class="col-sm-3 control-label">执行策略:</label>
<div class="col-sm-8"> <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="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="2" /> 执行一次 </label>
<label class="radio-box"> <input type="radio" name="misfirePolicy" value="3" /> 放弃执行 </label> <label class="radio-box"> <input type="radio" name="misfirePolicy" value="3" /> 放弃执行 </label>
</div> </div>
</div> </div>

View File

@ -5,44 +5,90 @@
<head th:include="include :: header"></head> <head th:include="include :: header"></head>
<body class="white-bg"> <body class="white-bg">
<div class="wrapper wrapper-content animated fadeInRight ibox-content"> <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"> <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 class="form-control-static" th:text="${jobLog.jobLogId}">
</div> </div>
</div> </div>
<div class="form-group"> <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 class="form-control-static" th:text="${jobLog.jobName}">
</div> </div>
</div> </div>
<div class="form-group"> <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 class="form-control-static" th:text="${jobLog.jobGroup}">
</div> </div>
</div> </div>
<div class="form-group"> <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.methodName} + '(' + ${jobLog.methodParams} + ')'"> <div class="form-control-static" th:text="${jobLog.methodName} + '(' + ${#strings.defaultString(jobLog.methodParams,'')} + ')'">
</div> </div>
</div> </div>
<div class="form-group"> <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 class="form-control-static" th:text="${jobLog.jobMessage}">
</div> </div>
</div> </div>
<div class="form-group"> <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 class="form-control-static" th:class="${jobLog.status == '0' ? 'label label-primary' : 'label label-danger'}" th:text="${jobLog.status == '0' ? '正常' : '失败'}">
</div> </div>
</div> </div>
<div class="form-group" th:style="'display:' + ${jobLog.status == '0' ? 'none' : 'block'}"> <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 class="form-control-static" th:text="${jobLog.exceptionInfo}">
</div> </div>
</div> </div>
</form> </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>
<div th:include="include :: footer"></div>
</body> </body>
</html> </html>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1,5 +1,6 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.lang.management.ManagementFactory;
import java.text.ParseException; import java.text.ParseException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
@ -120,4 +121,35 @@ public class DateUtils extends org.apache.commons.lang3.time.DateUtils
return null; 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 + "分钟";
}
} }

View File

@ -1,5 +1,7 @@
package com.ruoyi.common.utils; package com.ruoyi.common.utils;
import java.net.InetAddress;
import java.net.UnknownHostException;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
/** /**
@ -155,4 +157,28 @@ public class IpUtils
} }
return bytes; 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 "未知";
}
} }

View File

@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>ruoyi</artifactId> <artifactId>ruoyi</artifactId>
<groupId>com.ruoyi</groupId> <groupId>com.ruoyi</groupId>
<version>3.0</version> <version>3.1</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
@ -111,7 +111,6 @@
<version>${ruoyi.version}</version> <version>${ruoyi.version}</version>
</dependency> </dependency>
<!-- pagehelper 分页插件 --> <!-- pagehelper 分页插件 -->
<dependency> <dependency>
<groupId>com.github.pagehelper</groupId> <groupId>com.github.pagehelper</groupId>
@ -119,6 +118,23 @@
<version>${pagehelper.boot.version}</version> <version>${pagehelper.boot.version}</version>
</dependency> </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> </dependencies>
</project> </project>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -166,9 +166,10 @@ insert into sys_menu values('108', '日志管理', '1', '9', '#',
insert into sys_menu values('109', '在线用户', '2', '1', '/monitor/online', 'C', '0', 'monitor:online:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '在线用户菜单'); insert into sys_menu values('109', '在线用户', '2', '1', '/monitor/online', 'C', '0', 'monitor:online:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '在线用户菜单');
insert into sys_menu values('110', '定时任务', '2', '2', '/monitor/job', 'C', '0', 'monitor:job:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '定时任务菜单'); insert into sys_menu values('110', '定时任务', '2', '2', '/monitor/job', 'C', '0', 'monitor:job:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '定时任务菜单');
insert into sys_menu values('111', '数据监控', '2', '3', '/monitor/data', 'C', '0', 'monitor:data:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '数据监控菜单'); insert into sys_menu values('111', '数据监控', '2', '3', '/monitor/data', 'C', '0', 'monitor:data:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '数据监控菜单');
insert into sys_menu values('112', '表单构建', '3', '1', '/tool/build', 'C', '0', 'tool:build:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '表单构建菜单'); insert into sys_menu values('112', '服务监控', '2', '3', '/monitor/server', 'C', '0', 'monitor:server:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '数据监控菜单');
insert into sys_menu values('113', '代码生成', '3', '2', '/tool/gen', 'C', '0', 'tool:gen:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '代码生成菜单'); insert into sys_menu values('113', '表单构建', '3', '1', '/tool/build', 'C', '0', 'tool:build:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '表单构建菜单');
insert into sys_menu values('114', '系统接口', '3', '3', '/tool/swagger', 'C', '0', 'tool:swagger:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统接口菜单'); insert into sys_menu values('114', '代码生成', '3', '2', '/tool/gen', 'C', '0', 'tool:gen:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '代码生成菜单');
insert into sys_menu values('115', '系统接口', '3', '3', '/tool/swagger', 'C', '0', 'tool:swagger:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统接口菜单');
-- 三级菜单 -- 三级菜单
insert into sys_menu values('500', '操作日志', '108', '1', '/monitor/operlog', 'C', '0', 'monitor:operlog:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '操作日志菜单'); insert into sys_menu values('500', '操作日志', '108', '1', '/monitor/operlog', 'C', '0', 'monitor:operlog:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', '/monitor/logininfor', 'C', '0', 'monitor:logininfor:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '登录日志菜单'); insert into sys_menu values('501', '登录日志', '108', '2', '/monitor/logininfor', 'C', '0', 'monitor:logininfor:view', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '登录日志菜单');
@ -240,8 +241,8 @@ insert into sys_menu values('1052', '状态修改', '110', '5', '#', 'F', '0',
insert into sys_menu values('1053', '任务详细', '110', '6', '#', 'F', '0', 'monitor:job:detail', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_menu values('1053', '任务详细', '110', '6', '#', 'F', '0', 'monitor:job:detail', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
insert into sys_menu values('1054', '任务导出', '110', '7', '#', 'F', '0', 'monitor:job:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_menu values('1054', '任务导出', '110', '7', '#', 'F', '0', 'monitor:job:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- 代码生成按钮 -- 代码生成按钮
insert into sys_menu values('1055', '生成查询', '113', '1', '#', 'F', '0', 'tool:gen:list', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_menu values('1055', '生成查询', '114', '1', '#', 'F', '0', 'tool:gen:list', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
insert into sys_menu values('1056', '生成代码', '113', '2', '#', 'F', '0', 'tool:gen:code', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_menu values('1056', '生成代码', '114', '2', '#', 'F', '0', 'tool:gen:code', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- ---------------------------- -- ----------------------------
@ -292,6 +293,7 @@ insert into sys_role_menu values ('2', '111');
insert into sys_role_menu values ('2', '112'); insert into sys_role_menu values ('2', '112');
insert into sys_role_menu values ('2', '113'); insert into sys_role_menu values ('2', '113');
insert into sys_role_menu values ('2', '114'); insert into sys_role_menu values ('2', '114');
insert into sys_role_menu values ('2', '115');
insert into sys_role_menu values ('2', '500'); insert into sys_role_menu values ('2', '500');
insert into sys_role_menu values ('2', '501'); insert into sys_role_menu values ('2', '501');
insert into sys_role_menu values ('2', '1000'); insert into sys_role_menu values ('2', '1000');
@ -563,7 +565,7 @@ create table sys_job (
method_name varchar(500) default '' comment '任务方法', method_name varchar(500) default '' comment '任务方法',
method_params varchar(200) default '' comment '方法参数', method_params varchar(200) default '' comment '方法参数',
cron_expression varchar(255) default '' comment 'cron执行表达式', cron_expression varchar(255) default '' comment 'cron执行表达式',
misfire_policy varchar(20) default '1' comment '计划执行错误策略1继续 2等待 3放弃', misfire_policy varchar(20) default '3' comment '计划执行错误策略1立即执行 2执行一次 3放弃执行',
status char(1) default '0' comment '状态0正常 1暂停', status char(1) default '0' comment '状态0正常 1暂停',
create_by varchar(64) default '' comment '创建者', create_by varchar(64) default '' comment '创建者',
create_time datetime comment '创建时间', create_time datetime comment '创建时间',
@ -573,8 +575,8 @@ create table sys_job (
primary key (job_id, job_name, job_group) primary key (job_id, job_name, job_group)
) engine=innodb auto_increment=100 default charset=utf8 comment = '定时任务调度表'; ) engine=innodb auto_increment=100 default charset=utf8 comment = '定时任务调度表';
insert into sys_job values(1, 'ryTask', '系统默认(无参)', 'ryNoParams', '', '0/10 * * * * ?', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_job values(1, 'ryTask', '系统默认(无参)', 'ryNoParams', '', '0/10 * * * * ?', '3', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
insert into sys_job values(2, 'ryTask', '系统默认(有参)', 'ryParams', 'ry', '0/20 * * * * ?', '1', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', ''); insert into sys_job values(2, 'ryTask', '系统默认(有参)', 'ryParams', 'ry', '0/20 * * * * ?', '3', '1', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- ---------------------------- -- ----------------------------