pre-release 2.3.2

This commit is contained in:
jiangzeyin 2019-04-15 16:02:27 +08:00
parent c3c269e5aa
commit c998510ab9
18 changed files with 280 additions and 289 deletions

View File

@ -9,8 +9,8 @@
<a target="_blank" href="https://travis-ci.org/jiangzeyin/Jpom"> <a target="_blank" href="https://travis-ci.org/jiangzeyin/Jpom">
<img src='https://travis-ci.org/jiangzeyin/Jpom.svg?branch=master' alt='travis'></img> <img src='https://travis-ci.org/jiangzeyin/Jpom.svg?branch=master' alt='travis'></img>
</a> </a>
<a href="https://www.codacy.com/app/jiangzeyin/Jpom?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=jiangzeyin/Jpom&amp;utm_campaign=Badge_Grade"> <a target="_blank" href="https://www.codacy.com/app/jiangzeyin/Jpom?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=jiangzeyin/Jpom&amp;utm_campaign=Badge_Grade">
<img src="https://api.codacy.com/project/badge/Grade/9c97dc9925c84404b63e15fefbacc984"/> <img src="https://api.codacy.com/project/badge/Grade/9c97dc9925c84404b63e15fefbacc984"></img>
</a> </a>
<a target="_blank" href="https://shang.qq.com/wpa/qunwpa?idkey=7be1882a2e2f07cd4af28bbb1f13362af270ba4615f2a6c7aaf9605fc0563d1b"> <a target="_blank" href="https://shang.qq.com/wpa/qunwpa?idkey=7be1882a2e2f07cd4af28bbb1f13362af270ba4615f2a6c7aaf9605fc0563d1b">
<img src='https://img.shields.io/badge/QQ%E7%BE%A4-136715345-yellowgreen.svg' alt='136715345'></img> <img src='https://img.shields.io/badge/QQ%E7%BE%A4-136715345-yellowgreen.svg' alt='136715345'></img>
@ -31,7 +31,7 @@
> 当多个项目运行在同一台服务器时运维人员通常也不只一个如果每个人都登录服务器管理项目难免会造成一些不必要的麻烦甚至给服务器的安全性带来问题服务器密码知道的人越多越容易泄露因为不需要登录服务器管理项目维护人员不需要知道服务器的登录密码只需要有Jpom的账号就行Jpom本身可以通过权限管理给不同用户不同的权限这样也使得项目的稳定性得到提升。 > 当多个项目运行在同一台服务器时运维人员通常也不只一个如果每个人都登录服务器管理项目难免会造成一些不必要的麻烦甚至给服务器的安全性带来问题服务器密码知道的人越多越容易泄露因为不需要登录服务器管理项目维护人员不需要知道服务器的登录密码只需要有Jpom的账号就行Jpom本身可以通过权限管理给不同用户不同的权限这样也使得项目的稳定性得到提升。
> Jpom可以在linux和windows服务器上运行 > Jpom可以在Linux和Windows服务器上运行
### Jpom 目标 ### Jpom 目标

View File

@ -16,7 +16,7 @@ import cn.keepbx.jpom.common.commander.impl.LinuxCommander;
import cn.keepbx.jpom.common.commander.impl.WindowsCommander; import cn.keepbx.jpom.common.commander.impl.WindowsCommander;
import cn.keepbx.jpom.model.NetstatModel; import cn.keepbx.jpom.model.NetstatModel;
import cn.keepbx.jpom.model.ProjectInfoModel; import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.service.manage.CommandService; import cn.keepbx.jpom.service.manage.ConsoleService;
import com.sun.tools.attach.AttachNotSupportedException; import com.sun.tools.attach.AttachNotSupportedException;
import com.sun.tools.attach.VirtualMachine; import com.sun.tools.attach.VirtualMachine;
import com.sun.tools.attach.VirtualMachineDescriptor; import com.sun.tools.attach.VirtualMachineDescriptor;
@ -255,9 +255,9 @@ public abstract class AbstractCommander {
public String status(String tag) throws Exception { public String status(String tag) throws Exception {
VirtualMachine virtualMachine = getVirtualMachine(tag); VirtualMachine virtualMachine = getVirtualMachine(tag);
if (virtualMachine == null) { if (virtualMachine == null) {
return CommandService.STOP_TAG; return ConsoleService.STOP_TAG;
} }
return StrUtil.format("{}:{}", CommandService.RUNING_TAG, virtualMachine.id()); return StrUtil.format("{}:{}", ConsoleService.RUNING_TAG, virtualMachine.id());
} }
/** /**
@ -314,7 +314,7 @@ public abstract class AbstractCommander {
* @return int * @return int
*/ */
protected static int parsePid(String result) { protected static int parsePid(String result) {
if (result.startsWith(CommandService.RUNING_TAG)) { if (result.startsWith(ConsoleService.RUNING_TAG)) {
return Convert.toInt(result.split(":")[1]); return Convert.toInt(result.split(":")[1]);
} }
return 0; return 0;
@ -329,7 +329,7 @@ public abstract class AbstractCommander {
*/ */
public boolean isRun(String tag) throws Exception { public boolean isRun(String tag) throws Exception {
String result = status(tag); String result = status(tag);
return result.contains(CommandService.RUNING_TAG); return result.contains(ConsoleService.RUNING_TAG);
} }
/*** /***

View File

@ -4,7 +4,6 @@ import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.JsonMessage; import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseController; import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.commander.AbstractCommander; import cn.keepbx.jpom.common.commander.AbstractCommander;
import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.system.TopManager; import cn.keepbx.jpom.system.TopManager;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
import org.springframework.http.MediaType; import org.springframework.http.MediaType;
@ -24,8 +23,6 @@ public class WelcomeController extends BaseController {
@RequestMapping(value = "welcome", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(value = "welcome", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String welcome() { public String welcome() {
UserModel userName = getUser();
setAttribute("userInfo", userName.getUserMd5Key());
return "welcome"; return "welcome";
} }

View File

@ -8,7 +8,7 @@ import cn.jiangzeyin.common.JsonMessage;
import cn.keepbx.jpom.common.BaseController; import cn.keepbx.jpom.common.BaseController;
import cn.keepbx.jpom.common.interceptor.ProjectPermission; import cn.keepbx.jpom.common.interceptor.ProjectPermission;
import cn.keepbx.jpom.model.ProjectInfoModel; import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.service.manage.CommandService; import cn.keepbx.jpom.service.manage.ConsoleService;
import cn.keepbx.jpom.service.manage.ProjectInfoService; import cn.keepbx.jpom.service.manage.ProjectInfoService;
import cn.keepbx.jpom.service.oss.OssManagerService; import cn.keepbx.jpom.service.oss.OssManagerService;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
@ -36,7 +36,7 @@ public class BuildController extends BaseController {
@Resource @Resource
private ProjectInfoService projectInfoService; private ProjectInfoService projectInfoService;
@Resource @Resource
private CommandService commandService; private ConsoleService consoleService;
@RequestMapping(value = "build", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE) @RequestMapping(value = "build", method = RequestMethod.GET, produces = MediaType.TEXT_HTML_VALUE)
public String build(String id) { public String build(String id) {
@ -86,7 +86,7 @@ public class BuildController extends BaseController {
// 修改使用状态 // 修改使用状态
projectInfoModel.setUseLibDesc("build"); projectInfoModel.setUseLibDesc("build");
projectInfoService.updateItem(projectInfoModel); projectInfoService.updateItem(projectInfoModel);
String result = commandService.execCommand(CommandService.CommandOp.restart, projectInfoModel); String result = consoleService.execCommand(ConsoleService.CommandOp.restart, projectInfoModel);
return JsonMessage.getString(200, "安装成功,已自动重启,当前状态是:" + result); return JsonMessage.getString(200, "安装成功,已自动重启,当前状态是:" + result);
} }
} }

View File

@ -37,7 +37,6 @@ public class ConsoleController extends BaseController {
if (projectInfoModel != null) { if (projectInfoModel != null) {
UserModel userName = getUser(); UserModel userName = getUser();
setAttribute("projectInfo", projectInfoModel); setAttribute("projectInfo", projectInfoModel);
setAttribute("userInfo", userName.getUserMd5Key());
String logSize = projectInfoService.getLogSize(id); String logSize = projectInfoService.getLogSize(id);
setAttribute("logSize", logSize); setAttribute("logSize", logSize);
setAttribute("manager", userName.isProject(id)); setAttribute("manager", userName.isProject(id));
@ -52,5 +51,4 @@ public class ConsoleController extends BaseController {
} }
} }

View File

@ -86,6 +86,11 @@ public class JpomManifest {
return version; return version;
} }
/**
* 判断当前是否为调试模式
*
* @return jar 为非调试模式
*/
public boolean isDebug() { public boolean isDebug() {
return "dev".equals(getVersion()); return "dev".equals(getVersion());
} }

View File

@ -7,12 +7,13 @@ import org.springframework.stereotype.Service;
import javax.annotation.Resource; import javax.annotation.Resource;
/** /**
* 控制台
* Created by jiangzeyin on 2018/9/28. * Created by jiangzeyin on 2018/9/28.
* *
* @author jiangzeyin * @author jiangzeyin
*/ */
@Service @Service
public class CommandService { public class ConsoleService {
public static final String RUNING_TAG = "running"; public static final String RUNING_TAG = "running";
public static final String STOP_TAG = "stopped"; public static final String STOP_TAG = "stopped";

View File

@ -58,19 +58,16 @@ public class CertService extends BaseOperService<CertModel> {
*/ */
public boolean delete(String id) { public boolean delete(String id) {
try { try {
JSONObject jsonObject = getJSONObject(ConfigBean.CERT); CertModel certModel = getItem(id);
if (jsonObject == null) { if (certModel == null) {
return false;
}
JSONObject cert = jsonObject.getJSONObject(id);
if (cert == null) {
return true; return true;
} }
String keyPath = cert.getString("key"); String keyPath = certModel.getCert();
deleteJson(ConfigBean.CERT, id); deleteJson(ConfigBean.CERT, id);
if (StrUtil.isNotEmpty(keyPath)) { if (StrUtil.isNotEmpty(keyPath)) {
// 删除证书文件
File parentFile = FileUtil.file(keyPath).getParentFile(); File parentFile = FileUtil.file(keyPath).getParentFile();
return FileUtil.del(parentFile); FileUtil.del(parentFile);
} }
} catch (Exception e) { } catch (Exception e) {
DefaultSystemLog.ERROR().error(e.getMessage(), e); DefaultSystemLog.ERROR().error(e.getMessage(), e);

View File

@ -7,7 +7,7 @@ import cn.jiangzeyin.common.JsonMessage;
import cn.jiangzeyin.common.spring.SpringUtil; import cn.jiangzeyin.common.spring.SpringUtil;
import cn.keepbx.jpom.model.ProjectInfoModel; import cn.keepbx.jpom.model.ProjectInfoModel;
import cn.keepbx.jpom.model.UserModel; import cn.keepbx.jpom.model.UserModel;
import cn.keepbx.jpom.service.manage.CommandService; import cn.keepbx.jpom.service.manage.ConsoleService;
import cn.keepbx.jpom.service.manage.ProjectInfoService; import cn.keepbx.jpom.service.manage.ProjectInfoService;
import cn.keepbx.jpom.service.user.UserService; import cn.keepbx.jpom.service.user.UserService;
import cn.keepbx.jpom.system.TopManager; import cn.keepbx.jpom.system.TopManager;
@ -32,7 +32,7 @@ import java.util.concurrent.atomic.AtomicInteger;
public class LogWebSocketHandle { public class LogWebSocketHandle {
public static final String SYSTEM_ID = "system"; public static final String SYSTEM_ID = "system";
private CommandService commandService; private ConsoleService consoleService;
private static volatile AtomicInteger onlineCount = new AtomicInteger(); private static volatile AtomicInteger onlineCount = new AtomicInteger();
private static final ConcurrentHashMap<String, UserModel> USER = new ConcurrentHashMap<>(); private static final ConcurrentHashMap<String, UserModel> USER = new ConcurrentHashMap<>();
@ -45,8 +45,8 @@ public class LogWebSocketHandle {
*/ */
@OnOpen @OnOpen
public void onOpen(@PathParam("userInfo") String userInfo, @PathParam("projectId") String projectId, Session session) { public void onOpen(@PathParam("userInfo") String userInfo, @PathParam("projectId") String projectId, Session session) {
if (commandService == null) { if (consoleService == null) {
commandService = SpringUtil.getBean(CommandService.class); consoleService = SpringUtil.getBean(ConsoleService.class);
} }
// 通过用户名和密码的Md5值判断是否是登录的 // 通过用户名和密码的Md5值判断是否是登录的
try { try {
@ -100,8 +100,8 @@ public class LogWebSocketHandle {
String projectId = json.getString("projectId"); String projectId = json.getString("projectId");
ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class); ProjectInfoService projectInfoService = SpringUtil.getBean(ProjectInfoService.class);
ProjectInfoModel projectInfoModel = projectInfoService.getItem(projectId); ProjectInfoModel projectInfoModel = projectInfoService.getItem(projectId);
CommandService.CommandOp commandOp = CommandService.CommandOp.valueOf(op); ConsoleService.CommandOp commandOp = ConsoleService.CommandOp.valueOf(op);
if (projectInfoModel == null && commandOp != CommandService.CommandOp.top) { if (projectInfoModel == null && commandOp != ConsoleService.CommandOp.top) {
SocketSessionUtil.send(session, "没有对应项目"); SocketSessionUtil.send(session, "没有对应项目");
return; return;
} }
@ -114,8 +114,8 @@ public class LogWebSocketHandle {
case start: case start:
case restart: case restart:
logUser = true; logUser = true;
strResult = commandService.execCommand(commandOp, projectInfoModel); strResult = consoleService.execCommand(commandOp, projectInfoModel);
if (strResult.contains(CommandService.RUNING_TAG)) { if (strResult.contains(ConsoleService.RUNING_TAG)) {
resultData = JsonMessage.toJson(200, "操作成功:" + strResult); resultData = JsonMessage.toJson(200, "操作成功:" + strResult);
} else { } else {
resultData = JsonMessage.toJson(400, strResult); resultData = JsonMessage.toJson(400, strResult);
@ -124,8 +124,8 @@ public class LogWebSocketHandle {
case stop: case stop:
logUser = true; logUser = true;
// 停止项目 // 停止项目
strResult = commandService.execCommand(commandOp, projectInfoModel); strResult = consoleService.execCommand(commandOp, projectInfoModel);
if (strResult.contains(CommandService.STOP_TAG)) { if (strResult.contains(ConsoleService.STOP_TAG)) {
resultData = JsonMessage.toJson(200, "操作成功"); resultData = JsonMessage.toJson(200, "操作成功");
} else { } else {
resultData = JsonMessage.toJson(500, strResult); resultData = JsonMessage.toJson(500, strResult);
@ -133,8 +133,8 @@ public class LogWebSocketHandle {
break; break;
case status: case status:
// 获取项目状态 // 获取项目状态
strResult = commandService.execCommand(commandOp, projectInfoModel); strResult = consoleService.execCommand(commandOp, projectInfoModel);
if (strResult.contains(CommandService.RUNING_TAG)) { if (strResult.contains(ConsoleService.RUNING_TAG)) {
resultData = JsonMessage.toJson(200, "运行中", strResult); resultData = JsonMessage.toJson(200, "运行中", strResult);
} else { } else {
resultData = JsonMessage.toJson(404, "未运行", strResult); resultData = JsonMessage.toJson(404, "未运行", strResult);

View File

@ -6,10 +6,8 @@ import cn.hutool.core.util.StrUtil;
import cn.hutool.cron.CronUtil; import cn.hutool.cron.CronUtil;
import cn.hutool.cron.Scheduler; import cn.hutool.cron.Scheduler;
import cn.jiangzeyin.common.DefaultSystemLog; import cn.jiangzeyin.common.DefaultSystemLog;
import cn.jiangzeyin.common.spring.SpringUtil;
import cn.jiangzeyin.pool.ThreadPoolService; import cn.jiangzeyin.pool.ThreadPoolService;
import cn.keepbx.jpom.common.commander.AbstractCommander; import cn.keepbx.jpom.common.commander.AbstractCommander;
import cn.keepbx.jpom.service.manage.CommandService;
import cn.keepbx.jpom.socket.SocketSessionUtil; import cn.keepbx.jpom.socket.SocketSessionUtil;
import cn.keepbx.jpom.util.JvmUtil; import cn.keepbx.jpom.util.JvmUtil;
import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONArray;
@ -39,9 +37,11 @@ public class TopManager {
private static final Set<Session> SESSIONS = new HashSet<>(); private static final Set<Session> SESSIONS = new HashSet<>();
private static final String CRON_ID = "topMonitor"; private static final String CRON_ID = "topMonitor";
private static CommandService commandService;
private static boolean watch = false;
private static ExecutorService executorService = ThreadPoolService.newCachedThreadPool(TopManager.class); private static ExecutorService executorService = ThreadPoolService.newCachedThreadPool(TopManager.class);
/**
* 是否开启首页监听自动刷新
*/
private static final AtomicBoolean WATCH = new AtomicBoolean(false);
/** /**
* 锁定查看进程信息 * 锁定查看进程信息
*/ */
@ -71,12 +71,9 @@ public class TopManager {
* 创建定时执行top * 创建定时执行top
*/ */
private static void addCron() { private static void addCron() {
if (watch) { if (WATCH.get()) {
return; return;
} }
if (commandService == null) {
commandService = SpringUtil.getBean(CommandService.class);
}
CronUtil.remove(CRON_ID); CronUtil.remove(CRON_ID);
CronUtil.schedule(CRON_ID, "0/5 * * * * ?", () -> { CronUtil.schedule(CRON_ID, "0/5 * * * * ?", () -> {
//发送监控信息 //发送监控信息
@ -99,7 +96,7 @@ public class TopManager {
if (!scheduler.isStarted()) { if (!scheduler.isStarted()) {
CronUtil.start(); CronUtil.start();
} }
watch = true; WATCH.set(true);
} }
@ -500,6 +497,6 @@ public class TopManager {
} }
// //
CronUtil.remove(CRON_ID); CronUtil.remove(CRON_ID);
watch = false; WATCH.set(false);
} }
} }

View File

@ -100,7 +100,36 @@
$.ajax(defData); $.ajax(defData);
} }
## 静默ajax
function silentAjax(data) { function silentAjax(data) {
loadingAjax(data, true); loadingAjax(data, true);
} }
## 默认表格渲染
function tableRender(data) {
var done = data.done;
delete data.done;
//
const defData = {
even: true,
loading: true,
method: 'POST',
response: {
statusCode: 200
},
done: function (data) {
if (data.code == 800) {
## 用户信息失效
layer.msg(data.msg);
setTimeout(function () {
top.location.reload();
}, 1500);
return;
}
done && done(data);
}
};
$.extend(defData, data);
table.render(defData);
}
</script> </script>

View File

@ -90,7 +90,7 @@
function loadSuccess() { function loadSuccess() {
const showLogDom = $('.console .terminal'); const showLogDom = $('.console .terminal');
if ('WebSocket' in window) { if ('WebSocket' in window) {
const ws = new WebSocket(getSocketHost() + "/console/$userInfo/$!projectInfo.id"); const ws = new WebSocket(getSocketHost() + "/console/$user.getUserMd5Key()/$!projectInfo.id");
ws.onopen = function () { ws.onopen = function () {
showLogDom.append('WebSocket连接成功<br/>'); showLogDom.append('WebSocket连接成功<br/>');
setMsg('status'); setMsg('status');

View File

@ -41,13 +41,10 @@
function loadSuccess() { function loadSuccess() {
layui.use(['upload'], function () { layui.use(['upload'], function () {
var upload = layui.upload; var upload = layui.upload;
table.render({ tableRender({
id: 'table_file', id: 'table_file',
elem: '#tab_file', elem: '#tab_file',
url: './getFileList', url: './getFileList',
method: 'post',
// height: 'full',
even: true,
where: { where: {
id: '$id' id: '$id'
}, },
@ -65,10 +62,6 @@
{field: 'filesize', title: '文件大小', sort: true, width: '15%'}, {field: 'filesize', title: '文件大小', sort: true, width: '15%'},
{field: 'op', title: '操作', toolbar: '#bar_projects'} {field: 'op', title: '操作', toolbar: '#bar_projects'}
]], ]],
loading: true,
response: {
statusCode: 200
},
done: function () { done: function () {
} }

View File

@ -91,13 +91,11 @@
if (project && project.group) { if (project && project.group) {
apiWhere.group = project.group; apiWhere.group = project.group;
} }
table.render({ tableRender({
id: 'table_project', id: 'table_project',
elem: '#tab_project', elem: '#tab_project',
url: './getProjectInfo', url: './getProjectInfo',
// height: 'full-52',
toolbar: '#toolbarDemo', toolbar: '#toolbarDemo',
even: true,
where: apiWhere, where: apiWhere,
cols: [[{ cols: [[{
field: 'name', title: '项目名称', width: '15%', sort: true, templet: function (d) { field: 'name', title: '项目名称', width: '15%', sort: true, templet: function (d) {
@ -124,11 +122,6 @@
}, },
{field: 'op', title: '操作', toolbar: '#bar_projects'} {field: 'op', title: '操作', toolbar: '#bar_projects'}
]], ]],
loading: true,
method: 'POST',
response: {
statusCode: 200
},
done: function (data) { done: function (data) {
var projects = data.data; var projects = data.data;
var ids = []; var ids = [];

View File

@ -170,24 +170,30 @@
layer.msg("上传失败"); layer.msg("上传失败");
} }
}); });
table.render({ tableRender({
id: 'tab_certificate', id: 'tab_certificate',
elem: '#tab_certificate', elem: '#tab_certificate',
url: './getCertList', url: './getCertList',
// height: 'full-52',
even: true,
cols: [[ cols: [[
{field: 'id', title: 'id', width: '10%'}, {field: 'id', title: 'id', width: '10%', sort: true},
{field: 'name', title: '名称'}, {field: 'name', title: '名称', sort: true},
{field: 'domain', title: '域名'}, {field: 'domain', title: '域名', sort: true},
{field: 'effectiveTime', templet: "#tem_effectiveTime", title: '生效时间', width: '14%'}, {
{field: 'expirationTime', templet: "#tem_expirationTime", title: '到期时间', width: '14%'}, field: 'effectiveTime',
templet: "#tem_effectiveTime",
title: '生效时间',
width: '14%',
sort: true
},
{
field: 'expirationTime',
templet: "#tem_expirationTime",
title: '到期时间',
width: '14%',
sort: true
},
{field: 'op', title: '操作', align: 'center', toolbar: '#bar_cert', fixed: 'right'} {field: 'op', title: '操作', align: 'center', toolbar: '#bar_cert', fixed: 'right'}
]], ]]
loading: true,
response: {
statusCode: 200
}
}); });
// 表格工具条事件 // 表格工具条事件

View File

@ -79,27 +79,21 @@
}); });
} }
table.render({ tableRender({
id: 'tab_ngx', id: 'tab_ngx',
elem: '#tab_ngx', elem: '#tab_ngx',
url: './list_data.json', url: './list_data.json',
method: 'POST',
even: true,
cols: [[ cols: [[
{field: 'name', title: '文件名'}, {field: 'name', title: '文件名', sort: true},
{field: 'serverCount', title: '数量', width: "5%"}, {field: 'serverCount', title: '数量', width: "5%", sort: true},
{field: 'server_name', title: '域名'}, {field: 'server_name', title: '域名', sort: true},
{field: 'location', title: '根location'}, {field: 'location', title: '根location', sort: true},
{field: 'listen', title: '监听端口', width: "10%"}, {field: 'listen', title: '监听端口', width: "10%", sort: true},
{field: 'time', title: '最后修改时间'}, {field: 'time', title: '最后修改时间', sort: true},
{ {
field: 'op', title: '操作', align: 'center', toolbar: '#bar_ngx', fixed: 'right' field: 'op', title: '操作', align: 'center', toolbar: '#bar_ngx', fixed: 'right'
} }
]], ]]
loading: true,
response: {
statusCode: 200
}
}); });
// 删除 // 删除

View File

@ -122,24 +122,17 @@
<script type="text/javascript"> <script type="text/javascript">
function loadSuccess() { function loadSuccess() {
table.render({ tableRender({
id: 'tab_user', id: 'tab_user',
elem: '#tab_user', elem: '#tab_user',
url: './getUserList', url: './getUserList',
// height: 'full-52',
method: 'POST',
even: true,
cols: [[ cols: [[
{field: 'id', title: 'id'}, {field: 'id', title: 'id'},
{field: 'name', title: '昵称'}, {field: 'name', title: '昵称'},
{field: 'manage', templet: "#manager_status", title: '是否是管理员'}, {field: 'manage', templet: "#manager_status", title: '是否是管理员'},
{field: 'parent', title: '创建人'}, {field: 'parent', title: '创建人'},
{field: 'op', title: '操作', align: 'center', toolbar: '#bar_projects', fixed: 'right'} {field: 'op', title: '操作', align: 'center', toolbar: '#bar_projects', fixed: 'right'}
]], ]]
loading: true,
response: {
statusCode: 200
}
}); });
// 编辑用户信息 // 编辑用户信息

View File

@ -72,208 +72,196 @@
<table class="layui-table" id="tab_monitor" lay-filter="tab_monitor"></table> <table class="layui-table" id="tab_monitor" lay-filter="tab_monitor"></table>
</body> </body>
<script type="application/javascript"> <script type="application/javascript">
var ws, myEcharts;
var config = {
id: 'tab_monitor',
elem: '#tab_monitor',
cols: [[
{field: 'pid', title: '进程id', sort: true, width: '6%'},
{field: 'COMMAND', title: '进程名称'},
{field: 'port', title: '端口', sort: true, width: '6%'},
{field: 'USER', title: '所有者', width: '8%'},
{field: 'RES', title: '物理内存', width: '8%', sort: true},
{field: 'S', title: '进程状态', width: '8%', sort: true},
{field: 'CPU', title: '占用CPU', width: '8%', sort: true},
{field: 'MEM', title: '物理内存', width: '8%', sort: true},
{field: 'TIME', title: '时间总计', sort: true},
{field: 'PR', title: '优先级', width: '6%', sort: true},
{field: 'NI', title: 'nice值', width: '6%', sort: true},
{field: 'VIRT', title: '虚拟内存', width: '8%', sort: true},
{field: 'SHR', title: '共享内存', width: '8%', sort: true},
]],
done: function (data) {
}
};
function loadSuccess() { function loadSuccess() {
var ws, myEcharts; var top = layui.data('top');
loadData(); var openTop = false;
if (top) {
function loadData() { openTop = top.openTop;
var top = layui.data('top');
var openTop = false;
if (top) {
openTop = top.openTop;
}
//加载进程信息
loadProcessList();
if (openTop) {
$("#monitor").attr("checked", true);
linkSocket(openTop);
} else {
$("#monitor").attr("checked", false);
loadFirstEcharts();
}
form.render();
} }
//加载进程信息
var config = { loadProcessList();
id: 'tab_monitor', //
elem: '#tab_monitor', loadTop();
// height: 'full-52', $("#monitor").attr("checked", openTop);
even: true, if (openTop) {
cols: [[ linkSocket(openTop);
{field: 'pid', title: '进程id', sort: true, width: '6%'},
{field: 'COMMAND', title: '进程名称'},
{field: 'port', title: '端口', sort: true, width: '6%'},
{field: 'USER', title: '所有者', width: '8%'},
{field: 'RES', title: '物理内存', width: '8%', sort: true},
{field: 'S', title: '进程状态', width: '8%', sort: true},
{field: 'CPU', title: '占用CPU', width: '8%', sort: true},
{field: 'MEM', title: '物理内存', width: '8%', sort: true},
{field: 'TIME', title: '时间总计', sort: true},
{field: 'PR', title: '优先级', width: '6%', sort: true},
{field: 'NI', title: 'nice值', width: '6%', sort: true},
{field: 'VIRT', title: '虚拟内存', width: '8%', sort: true},
{field: 'SHR', title: '共享内存', width: '8%', sort: true},
]],
loading: true,
method: 'POST',
response: {
statusCode: 200
},
done: function (data) {
}
};
table.render(config);
function loadFirstEcharts() {
silentAjax({
url: './getTop',
success: function (data) {
if (200 == data.code) {
if (data.data) {
var top = JSON.parse(data.data);
loadEcharts(top);
}
} else {
layer.alert(data.msg);
}
}
});
} }
form.render();
function loadProcessList() { //
silentAjax({ tableRender(config);
url: './processList', // 切换
success: function (data) {
if (200 == data.code) {
if (data.data) {
config.data = data.data;
table.render(config);
}
} else {
layer.alert(data.msg);
}
}
});
}
function linkSocket(status) {
if (!ws) {
ws = new WebSocket(getSocketHost() + "/console/$userInfo/system");
}
if (status) {
if (ws.readyState != 1 && ws.readyState != 0) {
ws = new WebSocket(getSocketHost() + "/console/$userInfo/system");
}
ws.onopen = function () {
ws.send('{"op": "top", "projectInfo":{}}');
};
ws.onmessage = function (data) {
try {
if (data.data) {
var top = JSON.parse(data.data);
if (top.top) {
loadEcharts(top);
}
if (top.processList) {
var processList = top.processList;
config.data = processList;
table.render(config);
}
}
} catch (e) {
return;
}
};
ws.onerror = function (ev) {
};
} else {
ws.close();
}
}
form.on('switch(filter)', function (data) { form.on('switch(filter)', function (data) {
var check = data.elem.checked; var check = data.elem.checked;
layui.data('top', { layui.data('top', {
key: 'openTop', key: 'openTop',
value: check value: check
}); });
if ('WebSocket' in window) { linkSocket(check);
linkSocket(check); });
} }
})
//加载病状图 //加载病状图
function loadEcharts(top) { function loadEcharts(top) {
if (!top) { if (!top) {
return; return;
}
var cpu = top.cpu;
var value = [];
if (cpu) {
info = {
name: 'cpu',
type: 'pie',
center: ['18%', '50%'],
radius: ['40%', '70%'],
data: cpu
}
value.push(info);
}
var memory = top.memory;
if (memory) {
info = {
name: '内存',
type: 'pie',
center: ['48%', '50%'],
radius: ['40%', '70%'],
data: memory
}
value.push(info);
}
var disk = top.disk;
if (disk) {
info = {
name: '磁盘',
type: 'pie',
center: ['78%', '50%'],
radius: ['40%', '70%'],
data: disk
}
value.push(info);
}
var option = {
tooltip: {
trigger: 'item',
formatter: function (params, ticket, callback) {
var value = params.value;
var type = params.data.type;
var suffix = "";
if ("cpu" != type) {
suffix = " KB";
if (value > 1024) {
value = value / 1024;
suffix = " MB";
}
if (value > 1024) {
value = value / 1024;
suffix = " GB";
}
value = Math.round(value * 100) / 100;
} else {
value = Math.round(value * 10000) / 10000;
}
return params.seriesName + '<br/>' + params.name + " : " + value + suffix + "(" + params.percent + "%)";
}
},
series: value
};
if (!myEcharts) {
myEcharts = echarts.init(document.getElementById('echarts'));
}
myEcharts.setOption(option);
} }
var cpu = top.cpu;
var value = [];
if (cpu) {
info = {
name: 'cpu',
type: 'pie',
center: ['18%', '50%'],
radius: ['40%', '70%'],
data: cpu
}
value.push(info);
}
var memory = top.memory;
if (memory) {
info = {
name: '内存',
type: 'pie',
center: ['48%', '50%'],
radius: ['40%', '70%'],
data: memory
}
value.push(info);
}
var disk = top.disk;
if (disk) {
info = {
name: '磁盘',
type: 'pie',
center: ['78%', '50%'],
radius: ['40%', '70%'],
data: disk
}
value.push(info);
}
var option = {
tooltip: {
trigger: 'item',
formatter: function (params, ticket, callback) {
var value = params.value;
var type = params.data.type;
var suffix = "";
if ("cpu" != type) {
suffix = " KB";
if (value > 1024) {
value = value / 1024;
suffix = " MB";
}
if (value > 1024) {
value = value / 1024;
suffix = " GB";
}
value = Math.round(value * 100) / 100;
} else {
value = Math.round(value * 10000) / 10000;
}
return params.seriesName + '<br/>' + params.name + " : " + value + suffix + "(" + params.percent + "%)";
}
},
series: value
};
if (!myEcharts) {
myEcharts = echarts.init(document.getElementById('echarts'));
}
myEcharts.setOption(option);
}
function loadTop() {
silentAjax({
url: './getTop',
success: function (data) {
if (200 == data.code) {
if (data.data) {
var top = JSON.parse(data.data);
loadEcharts(top);
}
} else {
layer.alert(data.msg);
}
}
});
}
function loadProcessList() {
silentAjax({
url: './processList',
success: function (data) {
if (200 == data.code && data.data) {
config.data = data.data;
tableRender(config);
} else if (data.msg && data.msg != "") {
layer.alert(data.msg);
}
}
});
}
function linkSocket(status) {
if (!('WebSocket' in window)) {
layer.msg("不支持WebSocket");
return;
}
if (!ws) {
ws = new WebSocket(getSocketHost() + "/console/$user.getUserMd5Key()/system");
}
if (status) {
if (ws.readyState != 1 && ws.readyState != 0) {
ws = new WebSocket(getSocketHost() + "/console/$user.getUserMd5Key()/system");
}
ws.onopen = function () {
ws.send('{"op": "top", "projectInfo":{}}');
};
ws.onmessage = function (data) {
try {
if (data.data) {
var top = JSON.parse(data.data);
if (top.top) {
loadEcharts(top);
}
if (top.processList) {
var processList = top.processList;
config.data = processList;
tableRender(config);
}
}
} catch (e) {
return;
}
};
ws.onerror = function (ev) {
layer.msg("socket 异常");
};
} else {
ws.close();
}
} }
</script> </script>