From 86c7a763bce88be1cc4b7b3973cf8074b9cc8fd0 Mon Sep 17 00:00:00 2001
From: RuoYi <yzz_ivy@163.com>
Date: Thu, 24 Sep 2020 15:44:43 +0800
Subject: [PATCH] 新增在线用户管理
---
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java | 89 +++++++++
ruoyi-ui/src/views/monitor/online/index.vue | 124 +++++++++++++
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java | 92 ++++++++++
sql/ry_20200924.sql | 47 +++--
ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java | 2
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java | 13 -
sql/ry_config_20200924.sql | 4
ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java | 41 ++-
ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java | 15 +
ruoyi-ui/src/api/monitor/online.js | 18 ++
ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java | 48 +++++
11 files changed, 443 insertions(+), 50 deletions(-)
diff --git a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java
index b1c4257..3ff1799 100644
--- a/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java
+++ b/ruoyi-api/ruoyi-api-system/src/main/java/com/ruoyi/system/api/model/LoginUser.java
@@ -39,6 +39,11 @@
private Long expireTime;
/**
+ * 登录IP地址
+ */
+ private String ipaddr;
+
+ /**
* 权限列表
*/
private Set<String> permissions;
@@ -103,6 +108,16 @@
this.expireTime = expireTime;
}
+ public String getIpaddr()
+ {
+ return ipaddr;
+ }
+
+ public void setIpaddr(String ipaddr)
+ {
+ this.ipaddr = ipaddr;
+ }
+
public Set<String> getPermissions()
{
return permissions;
diff --git a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java
index 335ed91..be8712f 100644
--- a/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java
+++ b/ruoyi-common/ruoyi-common-core/src/main/java/com/ruoyi/common/core/utils/ip/IpUtils.java
@@ -14,34 +14,43 @@
{
public static String getIpAddr(HttpServletRequest request)
{
- if (request == null)
+ String ip = null;
+
+ // X-Forwarded-For:Squid 服务代理
+ String ipAddresses = request.getHeader("X-Forwarded-For");
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
- return "unknown";
+ // Proxy-Client-IP:apache 服务代理
+ ipAddresses = request.getHeader("Proxy-Client-IP");
}
- String ip = request.getHeader("x-forwarded-for");
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
- ip = request.getHeader("Proxy-Client-IP");
+ // WL-Proxy-Client-IP:weblogic 服务代理
+ ipAddresses = request.getHeader("WL-Proxy-Client-IP");
}
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
- ip = request.getHeader("X-Forwarded-For");
+ // HTTP_CLIENT_IP:有些代理服务器
+ ipAddresses = request.getHeader("HTTP_CLIENT_IP");
}
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ if (ipAddresses == null || ipAddresses.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
- ip = request.getHeader("WL-Proxy-Client-IP");
- }
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
- {
- ip = request.getHeader("X-Real-IP");
+ // X-Real-IP:nginx服务代理
+ ipAddresses = request.getHeader("X-Real-IP");
}
- if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip))
+ // 有些网络通过多层代理,那么获取到的ip就会有多个,一般都是通过逗号(,)分割开来,并且第一个ip为客户端的真实IP
+ if (ipAddresses != null && ipAddresses.length() != 0)
+ {
+ ip = ipAddresses.split(",")[0];
+ }
+
+ // 还是不能获取到,最后再通过request.getRemoteAddr();获取
+ if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ipAddresses))
{
ip = request.getRemoteAddr();
}
-
- return "0:0:0:0:0:0:0:1".equals(ip) ? "127.0.0.1" : ip;
+ return ip.equals("0:0:0:0:0:0:0:1") ? "127.0.0.1" : ip;
}
public static boolean internalIp(String ip)
diff --git a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
index 7c805c8..c5a6f35 100644
--- a/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
+++ b/ruoyi-common/ruoyi-common-security/src/main/java/com/ruoyi/common/security/service/TokenService.java
@@ -11,6 +11,7 @@
import com.ruoyi.common.core.constant.Constants;
import com.ruoyi.common.core.utils.IdUtils;
import com.ruoyi.common.core.utils.ServletUtils;
+import com.ruoyi.common.core.utils.ip.IpUtils;
import com.ruoyi.common.redis.service.RedisService;
import com.ruoyi.system.api.model.LoginUser;
@@ -41,6 +42,7 @@
loginUser.setToken(token);
loginUser.setUserid(loginUser.getSysUser().getUserId());
loginUser.setUsername(loginUser.getSysUser().getUserName());
+ loginUser.setIpaddr(IpUtils.getIpAddr(ServletUtils.getRequest()));
refreshToken(loginUser);
// 保存或更新用户token
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java
new file mode 100644
index 0000000..747e671
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/controller/SysUserOnlineController.java
@@ -0,0 +1,92 @@
+package com.ruoyi.system.controller;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.web.bind.annotation.DeleteMapping;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import com.ruoyi.common.core.constant.CacheConstants;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.common.core.web.controller.BaseController;
+import com.ruoyi.common.core.web.domain.AjaxResult;
+import com.ruoyi.common.core.web.page.TableDataInfo;
+import com.ruoyi.common.log.annotation.Log;
+import com.ruoyi.common.log.enums.BusinessType;
+import com.ruoyi.common.redis.service.RedisService;
+import com.ruoyi.common.security.annotation.PreAuthorize;
+import com.ruoyi.system.api.model.LoginUser;
+import com.ruoyi.system.domain.SysUserOnline;
+import com.ruoyi.system.service.ISysUserOnlineService;
+
+/**
+ * 在线用户监控
+ *
+ * @author ruoyi
+ */
+@RestController
+@RequestMapping("/online")
+public class SysUserOnlineController extends BaseController
+{
+ @Autowired
+ private ISysUserOnlineService userOnlineService;
+
+ @Autowired
+ private RedisService redisService;
+
+ @PreAuthorize(hasPermi = "monitor:online:list")
+ @GetMapping("/list")
+ public TableDataInfo list(String ipaddr, String userName)
+ {
+ Collection<String> keys = redisService.keys(CacheConstants.LOGIN_TOKEN_KEY + "*");
+ List<SysUserOnline> userOnlineList = new ArrayList<SysUserOnline>();
+ for (String key : keys)
+ {
+ LoginUser user = redisService.getCacheObject(key);
+ if (StringUtils.isNotEmpty(ipaddr) && StringUtils.isNotEmpty(userName))
+ {
+ if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
+ {
+ userOnlineList.add(userOnlineService.selectOnlineByInfo(ipaddr, userName, user));
+ }
+ }
+ else if (StringUtils.isNotEmpty(ipaddr))
+ {
+ if (StringUtils.equals(ipaddr, user.getIpaddr()))
+ {
+ userOnlineList.add(userOnlineService.selectOnlineByIpaddr(ipaddr, user));
+ }
+ }
+ else if (StringUtils.isNotEmpty(userName))
+ {
+ if (StringUtils.equals(userName, user.getUsername()))
+ {
+ userOnlineList.add(userOnlineService.selectOnlineByUserName(userName, user));
+ }
+ }
+ else
+ {
+ userOnlineList.add(userOnlineService.loginUserToUserOnline(user));
+ }
+ }
+ Collections.reverse(userOnlineList);
+ userOnlineList.removeAll(Collections.singleton(null));
+ return getDataTable(userOnlineList);
+ }
+
+ /**
+ * 强退用户
+ */
+ @PreAuthorize(hasPermi = "monitor:online:forceLogout")
+ @Log(title = "在线用户", businessType = BusinessType.FORCE)
+ @DeleteMapping("/{tokenId}")
+ public AjaxResult forceLogout(@PathVariable String tokenId)
+ {
+ redisService.deleteObject(CacheConstants.LOGIN_TOKEN_KEY + tokenId);
+ return AjaxResult.success();
+ }
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
index e1495aa..d9c8df0 100644
--- a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/domain/SysUserOnline.java
@@ -10,9 +10,6 @@
/** 会话编号 */
private String tokenId;
- /** 部门名称 */
- private String deptName;
-
/** 用户名称 */
private String userName;
@@ -39,16 +36,6 @@
public void setTokenId(String tokenId)
{
this.tokenId = tokenId;
- }
-
- public String getDeptName()
- {
- return deptName;
- }
-
- public void setDeptName(String deptName)
- {
- this.deptName = deptName;
}
public String getUserName()
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java
new file mode 100644
index 0000000..dd602b2
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/ISysUserOnlineService.java
@@ -0,0 +1,48 @@
+package com.ruoyi.system.service;
+
+import com.ruoyi.system.api.model.LoginUser;
+import com.ruoyi.system.domain.SysUserOnline;
+
+/**
+ * 在线用户 服务层
+ *
+ * @author ruoyi
+ */
+public interface ISysUserOnlineService
+{
+ /**
+ * 通过登录地址查询信息
+ *
+ * @param ipaddr 登录地址
+ * @param user 用户信息
+ * @return 在线用户信息
+ */
+ public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user);
+
+ /**
+ * 通过用户名称查询信息
+ *
+ * @param userName 用户名称
+ * @param user 用户信息
+ * @return 在线用户信息
+ */
+ public SysUserOnline selectOnlineByUserName(String userName, LoginUser user);
+
+ /**
+ * 通过登录地址/用户名称查询信息
+ *
+ * @param ipaddr 登录地址
+ * @param userName 用户名称
+ * @param user 用户信息
+ * @return 在线用户信息
+ */
+ public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user);
+
+ /**
+ * 设置在线用户信息
+ *
+ * @param user 用户信息
+ * @return 在线用户
+ */
+ public SysUserOnline loginUserToUserOnline(LoginUser user);
+}
diff --git a/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java
new file mode 100644
index 0000000..dcb0325
--- /dev/null
+++ b/ruoyi-modules/ruoyi-system/src/main/java/com/ruoyi/system/service/impl/SysUserOnlineServiceImpl.java
@@ -0,0 +1,89 @@
+package com.ruoyi.system.service.impl;
+
+import org.springframework.stereotype.Service;
+import com.ruoyi.common.core.utils.StringUtils;
+import com.ruoyi.system.api.model.LoginUser;
+import com.ruoyi.system.domain.SysUserOnline;
+import com.ruoyi.system.service.ISysUserOnlineService;
+
+/**
+ * 在线用户 服务层处理
+ *
+ * @author ruoyi
+ */
+@Service
+public class SysUserOnlineServiceImpl implements ISysUserOnlineService
+{
+ /**
+ * 通过登录地址查询信息
+ *
+ * @param ipaddr 登录地址
+ * @param user 用户信息
+ * @return 在线用户信息
+ */
+ @Override
+ public SysUserOnline selectOnlineByIpaddr(String ipaddr, LoginUser user)
+ {
+ if (StringUtils.equals(ipaddr, user.getIpaddr()))
+ {
+ return loginUserToUserOnline(user);
+ }
+ return null;
+ }
+
+ /**
+ * 通过用户名称查询信息
+ *
+ * @param userName 用户名称
+ * @param user 用户信息
+ * @return 在线用户信息
+ */
+ @Override
+ public SysUserOnline selectOnlineByUserName(String userName, LoginUser user)
+ {
+ if (StringUtils.equals(userName, user.getUsername()))
+ {
+ return loginUserToUserOnline(user);
+ }
+ return null;
+ }
+
+ /**
+ * 通过登录地址/用户名称查询信息
+ *
+ * @param ipaddr 登录地址
+ * @param userName 用户名称
+ * @param user 用户信息
+ * @return 在线用户信息
+ */
+ @Override
+ public SysUserOnline selectOnlineByInfo(String ipaddr, String userName, LoginUser user)
+ {
+ if (StringUtils.equals(ipaddr, user.getIpaddr()) && StringUtils.equals(userName, user.getUsername()))
+ {
+ return loginUserToUserOnline(user);
+ }
+ return null;
+ }
+
+ /**
+ * 设置在线用户信息
+ *
+ * @param user 用户信息
+ * @return 在线用户
+ */
+ @Override
+ public SysUserOnline loginUserToUserOnline(LoginUser user)
+ {
+ if (StringUtils.isNull(user))
+ {
+ return null;
+ }
+ SysUserOnline sysUserOnline = new SysUserOnline();
+ sysUserOnline.setTokenId(user.getToken());
+ sysUserOnline.setUserName(user.getUsername());
+ sysUserOnline.setIpaddr(user.getIpaddr());
+ sysUserOnline.setLoginTime(user.getLoginTime());
+ return sysUserOnline;
+ }
+}
diff --git a/ruoyi-ui/src/api/monitor/online.js b/ruoyi-ui/src/api/monitor/online.js
new file mode 100644
index 0000000..228fe3b
--- /dev/null
+++ b/ruoyi-ui/src/api/monitor/online.js
@@ -0,0 +1,18 @@
+import request from '@/utils/request'
+
+// 查询在线用户列表
+export function list(query) {
+ return request({
+ url: '/system/online/list',
+ method: 'get',
+ params: query
+ })
+}
+
+// 强退用户
+export function forceLogout(tokenId) {
+ return request({
+ url: '/system/online/' + tokenId,
+ method: 'delete'
+ })
+}
diff --git a/ruoyi-ui/src/views/monitor/online/index.vue b/ruoyi-ui/src/views/monitor/online/index.vue
new file mode 100644
index 0000000..802e4d1
--- /dev/null
+++ b/ruoyi-ui/src/views/monitor/online/index.vue
@@ -0,0 +1,124 @@
+<template>
+ <div class="app-container">
+ <el-form :model="queryParams" ref="queryForm" :inline="true" label-width="68px">
+ <el-form-item label="登录地址" prop="ipaddr">
+ <el-input
+ v-model="queryParams.ipaddr"
+ placeholder="请输入登录地址"
+ clearable
+ size="small"
+ @keyup.enter.native="handleQuery"
+ />
+ </el-form-item>
+ <el-form-item label="用户名称" prop="userName">
+ <el-input
+ v-model="queryParams.userName"
+ placeholder="请输入用户名称"
+ clearable
+ size="small"
+ @keyup.enter.native="handleQuery"
+ />
+ </el-form-item>
+ <el-form-item>
+ <el-button type="cyan" icon="el-icon-search" size="mini" @click="handleQuery">搜索</el-button>
+ <el-button icon="el-icon-refresh" size="mini" @click="resetQuery">重置</el-button>
+ </el-form-item>
+
+ </el-form>
+ <el-table
+ v-loading="loading"
+ :data="list.slice((pageNum-1)*pageSize,pageNum*pageSize)"
+ style="width: 100%;"
+ >
+ <el-table-column label="序号" type="index" align="center">
+ <template slot-scope="scope">
+ <span>{{(pageNum - 1) * pageSize + scope.$index + 1}}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="会话编号" align="center" prop="tokenId" :show-overflow-tooltip="true" />
+ <el-table-column label="登录名称" align="center" prop="userName" :show-overflow-tooltip="true" />
+ <el-table-column label="主机" align="center" prop="ipaddr" :show-overflow-tooltip="true" />
+ <el-table-column label="登录时间" align="center" prop="loginTime" width="180">
+ <template slot-scope="scope">
+ <span>{{ parseTime(scope.row.loginTime) }}</span>
+ </template>
+ </el-table-column>
+ <el-table-column label="操作" align="center" class-name="small-padding fixed-width">
+ <template slot-scope="scope">
+ <el-button
+ size="mini"
+ type="text"
+ icon="el-icon-delete"
+ @click="handleForceLogout(scope.row)"
+ v-hasPermi="['monitor:online:forceLogout']"
+ >强退</el-button>
+ </template>
+ </el-table-column>
+ </el-table>
+
+ <pagination v-show="total>0" :total="total" :page.sync="pageNum" :limit.sync="pageSize" />
+ </div>
+</template>
+
+<script>
+import { list, forceLogout } from "@/api/monitor/online";
+
+export default {
+ name: "Online",
+ data() {
+ return {
+ // 遮罩层
+ loading: true,
+ // 总条数
+ total: 0,
+ // 表格数据
+ list: [],
+ pageNum: 1,
+ pageSize: 10,
+ // 查询参数
+ queryParams: {
+ ipaddr: undefined,
+ userName: undefined
+ }
+ };
+ },
+ created() {
+ this.getList();
+ },
+ methods: {
+ /** 查询登录日志列表 */
+ getList() {
+ this.loading = true;
+ list(this.queryParams).then(response => {
+ this.list = response.rows;
+ this.total = response.total;
+ this.loading = false;
+ });
+ },
+ /** 搜索按钮操作 */
+ handleQuery() {
+ this.pageNum = 1;
+ this.getList();
+ },
+ /** 重置按钮操作 */
+ resetQuery() {
+ this.resetForm("queryForm");
+ this.handleQuery();
+ },
+ /** 强退按钮操作 */
+ handleForceLogout(row) {
+ this.$confirm('是否确认强退名称为"' + row.userName + '"的数据项?', "警告", {
+ confirmButtonText: "确定",
+ cancelButtonText: "取消",
+ type: "warning"
+ }).then(function() {
+ return forceLogout(row.tokenId);
+ }).then(() => {
+ this.getList();
+ this.msgSuccess("强退成功");
+ }).catch(function() {});
+ }
+ }
+};
+</script>
+
diff --git a/sql/ry_20200921.sql b/sql/ry_20200924.sql
similarity index 95%
rename from sql/ry_20200921.sql
rename to sql/ry_20200924.sql
index 3fef967..5d2e600 100644
--- a/sql/ry_20200921.sql
+++ b/sql/ry_20200924.sql
@@ -170,13 +170,14 @@
insert into sys_menu values('106', '参数设置', '1', '7', 'config', 'system/config/index', 1, 0, 'C', '0', '0', 'system:config:list', 'edit', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '参数设置菜单');
insert into sys_menu values('107', '通知公告', '1', '9', 'notice', 'system/notice/index', 1, 0, 'C', '0', '0', 'system:notice:list', 'message', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '通知公告菜单');
insert into sys_menu values('108', '日志管理', '1', '10', 'log', 'system/log/index', 1, 0, 'M', '0', '0', '', 'log', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '日志管理菜单');
-insert into sys_menu values('109', '定时任务', '2', '1', 'job', 'monitor/job/index', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '定时任务菜单');
-insert into sys_menu values('110', 'Sentinel控制台', '2', '2', 'http://localhost:8718', '', 1, 0, 'C', '0', '0', 'monitor:sentinel:list', 'sentinel', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '流量控制菜单');
-insert into sys_menu values('111', 'Nacos控制台', '2', '3', 'http://localhost:8848/nacos', '', 1, 0, 'C', '0', '0', 'monitor:nacos:list', 'nacos', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '服务治理菜单');
-insert into sys_menu values('112', 'Admin控制台', '2', '4', 'http://localhost:9100/login', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '服务监控菜单');
-insert into sys_menu values('113', '表单构建', '3', '1', 'build', 'tool/build/index', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '表单构建菜单');
-insert into sys_menu values('114', '代码生成', '3', '2', 'gen', 'tool/gen/index', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '代码生成菜单');
-insert into sys_menu values('115', '系统接口', '3', '3', 'http://localhost:8080/swagger-ui.html', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统接口菜单');
+insert into sys_menu values('109', '在线用户', '2', '1', 'online', 'monitor/online/index', 1, 0, 'C', '0', '0', 'monitor:online:list', 'online', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '在线用户菜单');
+insert into sys_menu values('110', '定时任务', '2', '2', 'job', 'monitor/job/index', 1, 0, 'C', '0', '0', 'monitor:job:list', 'job', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '定时任务菜单');
+insert into sys_menu values('111', 'Sentinel控制台', '2', '3', 'http://localhost:8718', '', 1, 0, 'C', '0', '0', 'monitor:sentinel:list', 'sentinel', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '流量控制菜单');
+insert into sys_menu values('112', 'Nacos控制台', '2', '4', 'http://localhost:8848/nacos', '', 1, 0, 'C', '0', '0', 'monitor:nacos:list', 'nacos', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '服务治理菜单');
+insert into sys_menu values('113', 'Admin控制台', '2', '5', 'http://localhost:9100/login', '', 1, 0, 'C', '0', '0', 'monitor:server:list', 'server', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '服务监控菜单');
+insert into sys_menu values('114', '表单构建', '3', '1', 'build', 'tool/build/index', 1, 0, 'C', '0', '0', 'tool:build:list', 'build', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '表单构建菜单');
+insert into sys_menu values('115', '代码生成', '3', '2', 'gen', 'tool/gen/index', 1, 0, 'C', '0', '0', 'tool:gen:list', 'code', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '代码生成菜单');
+insert into sys_menu values('116', '系统接口', '3', '3', 'http://localhost:8080/swagger-ui.html', '', 1, 0, 'C', '0', '0', 'tool:swagger:list', 'swagger', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '系统接口菜单');
-- 三级菜单
insert into sys_menu values('500', '操作日志', '108', '1', 'operlog', 'system/operlog/index', 1, 0, 'C', '0', '0', 'system:operlog:list', 'form', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '操作日志菜单');
insert into sys_menu values('501', '登录日志', '108', '2', 'logininfor', 'system/logininfor/index', 1, 0, 'C', '0', '0', 'system:logininfor:list', 'logininfor', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '登录日志菜单');
@@ -235,20 +236,24 @@
insert into sys_menu values('1048', '登录查询', '501', '1', '#', '', 1, 0, 'F', '0', '0', 'system:logininfor:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
insert into sys_menu values('1049', '登录删除', '501', '2', '#', '', 1, 0, 'F', '0', '0', 'system:logininfor:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
insert into sys_menu values('1050', '日志导出', '501', '3', '#', '', 1, 0, 'F', '0', '0', 'system:logininfor:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+-- 在线用户按钮
+insert into sys_menu values('1051', '在线查询', '109', '1', '#', '', 1, 0, 'F', '0', '0', 'monitor:online:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1052', '批量强退', '109', '2', '#', '', 1, 0, 'F', '0', '0', 'monitor:online:batchLogout', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1053', '单条强退', '109', '3', '#', '', 1, 0, 'F', '0', '0', 'monitor:online:forceLogout', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- 定时任务按钮
-insert into sys_menu values('1051', '任务查询', '109', '1', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1052', '任务新增', '109', '2', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1053', '任务修改', '109', '3', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1054', '任务删除', '109', '4', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1055', '状态修改', '109', '5', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1056', '任务导出', '109', '7', '#', '', 1, 0, 'F', '0', '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', '1', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1055', '任务新增', '110', '2', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:add', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1056', '任务修改', '110', '3', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1057', '任务删除', '110', '4', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1058', '状态修改', '110', '5', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:changeStatus', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1059', '任务导出', '110', '7', '#', '', 1, 0, 'F', '0', '0', 'monitor:job:export', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- 代码生成按钮
-insert into sys_menu values('1057', '生成查询', '114', '1', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1058', '生成修改', '114', '2', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1059', '生成删除', '114', '3', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1060', '导入代码', '114', '2', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1061', '预览代码', '114', '4', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-insert into sys_menu values('1062', '生成代码', '114', '5', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1060', '生成查询', '115', '1', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:query', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1061', '生成修改', '115', '2', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:edit', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1062', '生成删除', '115', '3', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:remove', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1063', '导入代码', '115', '2', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:import', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1064', '预览代码', '115', '4', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:preview', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
+insert into sys_menu values('1065', '生成代码', '115', '5', '#', '', 1, 0, 'F', '0', '0', 'tool:gen:code', '#', 'admin', '2018-03-16 11-33-00', 'ry', '2018-03-16 11-33-00', '');
-- ----------------------------
@@ -301,6 +306,7 @@
insert into sys_role_menu values ('2', '113');
insert into sys_role_menu values ('2', '114');
insert into sys_role_menu values ('2', '115');
+insert into sys_role_menu values ('2', '116');
insert into sys_role_menu values ('2', '500');
insert into sys_role_menu values ('2', '501');
insert into sys_role_menu values ('2', '1000');
@@ -366,6 +372,9 @@
insert into sys_role_menu values ('2', '1060');
insert into sys_role_menu values ('2', '1061');
insert into sys_role_menu values ('2', '1062');
+insert into sys_role_menu values ('2', '1063');
+insert into sys_role_menu values ('2', '1064');
+insert into sys_role_menu values ('2', '1065');
-- ----------------------------
-- 8、角色和部门关联表 角色1-N部门
diff --git a/sql/ry_config_20200915.sql b/sql/ry_config_20200924.sql
similarity index 84%
rename from sql/ry_config_20200915.sql
rename to sql/ry_config_20200924.sql
index 0b10cf9..ea5f294 100644
--- a/sql/ry_config_20200915.sql
+++ b/sql/ry_config_20200924.sql
@@ -37,8 +37,8 @@
(3,'ruoyi-auth-dev.yml','DEFAULT_GROUP','spring: \r\n datasource:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n','868c15010a7a15c027d4c90a48aabb3e','2020-05-14 13:20:49','2020-06-09 16:30:50',NULL,'0:0:0:0:0:0:0:1','','','认证中心','null','null','yaml','null'),
(4,'ruoyi-monitor-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n security:\r\n user:\r\n name: ruoyi\r\n password: 123456\r\n boot:\r\n admin:\r\n ui:\r\n title: 若依服务状态监控\r\n','8e49d78998a7780d780305aeefe4fb1b','2020-05-19 15:14:01','2020-05-19 18:50:44',NULL,'0:0:0:0:0:0:0:1','','','监控中心','null','null','yaml','null'),
(5,'ruoyi-system-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.system\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n title: 系统模块接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n authorization:\r\n name: RuoYi OAuth\r\n auth-regex: ^.*$\r\n authorization-scope-list:\r\n - scope: server\r\n description: 客户端授权范围\r\n token-url-list:\r\n - http://localhost:8080/auth/oauth/token\r\n','06f95c879d284ec8031cc44805e62b50','2020-05-14 13:37:04','2020-07-02 20:03:46',NULL,'0:0:0:0:0:0:0:1','','','系统模块','null','null','yaml','null'),
-(6, 'ruoyi-gen-dev.yml', 'DEFAULT_GROUP', '# Spring\r\nspring: \r\n redis: \r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource: \r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.gen.domain\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n title: 代码生成接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n authorization:\r\n name: RuoYi OAuth\r\n auth-regex: ^.*$\r\n authorization-scope-list:\r\n - scope: server\r\n description: 客户端授权范围\r\n token-url-list:\r\n - http://localhost:8080/auth/oauth/token\r\n\r\n# 代码生成\r\ngen: \r\n # 作者\r\n author: ruoyi\r\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\r\n packageName: com.ruoyi.system\r\n # 自动去除表前缀,默认是false\r\n autoRemovePre: false\r\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\r\n tablePrefix: sys_\r\n', '3abebb22d6af12794b7d7eb642fbe5c1', '2020-05-14 13:54:50', '2020-09-24 01:24:18', NULL, '0:0:0:0:0:0:0:1', '', '', '代码生成', 'null', 'null', 'yaml', 'null'),
-(7, 'ruoyi-job-dev.yml', 'DEFAULT_GROUP', '# Spring\r\nspring: \r\n redis: \r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.job.domain\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n title: 定时任务接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n authorization:\r\n name: RuoYi OAuth\r\n auth-regex: ^.*$\r\n authorization-scope-list:\r\n - scope: server\r\n description: 客户端授权范围\r\n token-url-list:\r\n - http://localhost:8080/auth/oauth/token\r\n', 'ea1d6a288ec9f2a804a1540a0eb30c27', '2020-05-14 13:58:46', '2020-09-24 01:24:29', NULL, '0:0:0:0:0:0:0:1', '', '', '定时任务', 'null', 'null', 'yaml', 'null'),
+(6,'ruoyi-gen-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource: \r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.gen.domain\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n title: 代码生成接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n authorization:\r\n name: RuoYi OAuth\r\n auth-regex: ^.*$\r\n authorization-scope-list:\r\n - scope: server\r\n description: 客户端授权范围\r\n token-url-list:\r\n - http://localhost:8080/auth/oauth/token\r\n\r\n# 代码生成\r\ngen: \r\n # 作者\r\n author: ruoyi\r\n # 默认生成包路径 system 需改成自己的模块名称 如 system monitor tool\r\n packageName: com.ruoyi.system\r\n # 自动去除表前缀,默认是false\r\n autoRemovePre: false\r\n # 表前缀(生成类名不会包含表前缀,多个用逗号分隔)\r\n tablePrefix: sys_\r\n','02b9be6ad01ca44c992c41a020ec81aa','2020-05-14 13:54:50','2020-09-24 14:56:08',NULL,'0:0:0:0:0:0:0:1','','','代码生成','null','null','yaml','null'),
+(7,'ruoyi-job-dev.yml','DEFAULT_GROUP','# Spring\r\nspring: \r\n redis:\r\n host: localhost\r\n port: 6379\r\n password: \r\n datasource:\r\n driver-class-name: com.mysql.cj.jdbc.Driver\r\n url: jdbc:mysql://localhost:3306/ry-cloud?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8\r\n username: root\r\n password: password\r\n\r\n# Mybatis配置\r\nmybatis:\r\n # 搜索指定包别名\r\n typeAliasesPackage: com.ruoyi.job.domain\r\n # 配置mapper的扫描,找到所有的mapper.xml映射文件\r\n mapperLocations: classpath:mapper/**/*.xml\r\n\r\n# swagger 配置\r\nswagger:\r\n title: 定时任务接口文档\r\n license: Powered By ruoyi\r\n licenseUrl: https://ruoyi.vip\r\n authorization:\r\n name: RuoYi OAuth\r\n auth-regex: ^.*$\r\n authorization-scope-list:\r\n - scope: server\r\n description: 客户端授权范围\r\n token-url-list:\r\n - http://localhost:8080/auth/oauth/token\r\n','5033cbfb2c38780ac23f74954588ec4f','2020-05-14 13:58:46','2020-09-24 14:56:18',NULL,'0:0:0:0:0:0:0:1','','','定时任务','null','null','yaml','null'),
(8,'sentinel-ruoyi-gateway','DEFAULT_GROUP','[\r\n {\r\n \"resource\": \"ruoyi-auth\",\r\n \"count\": 500,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-system\",\r\n \"count\": 1000,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-gen\",\r\n \"count\": 200,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n },\r\n {\r\n \"resource\": \"ruoyi-job\",\r\n \"count\": 300,\r\n \"grade\": 1,\r\n \"limitApp\": \"default\",\r\n \"strategy\": 0,\r\n \"controlBehavior\": 0\r\n }\r\n]','9f3a3069261598f74220bc47958ec252','2020-06-09 12:14:01','2020-06-10 11:44:19',NULL,'0:0:0:0:0:0:0:1','','','null','null','null','json','null');
--
Gitblit v1.9.3