diff --git a/ant-design-vue-jeecg/src/api/login.js b/ant-design-vue-jeecg/src/api/login.js
index b3599899..7bd6344b 100644
--- a/ant-design-vue-jeecg/src/api/login.js
+++ b/ant-design-vue-jeecg/src/api/login.js
@@ -71,4 +71,17 @@ export function thirdLogin(token,thirdType) {
'Content-Type': 'application/json;charset=UTF-8'
}
})
+}
+
+/**
+ * 强退其他账号
+ * @param token
+ * @returns {*}
+ */
+export function forceLogout(parameter) {
+ return axios({
+ url: '/sys/online/forceLogout',
+ method: 'post',
+ data: parameter
+ })
}
\ No newline at end of file
diff --git a/ant-design-vue-jeecg/src/views/system/SysOnlineList.vue b/ant-design-vue-jeecg/src/views/system/SysOnlineList.vue
new file mode 100644
index 00000000..12b9db07
--- /dev/null
+++ b/ant-design-vue-jeecg/src/views/system/SysOnlineList.vue
@@ -0,0 +1,158 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 查询
+ 重置
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ handleForce(record)">
+ 强退
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/DruidConfig.java b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/DruidConfig.java
new file mode 100644
index 00000000..c8a2ed64
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-base/jeecg-boot-base-core/src/main/java/org/jeecg/config/DruidConfig.java
@@ -0,0 +1,81 @@
+package org.jeecg.config;
+
+import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceAutoConfigure;
+import com.alibaba.druid.spring.boot.autoconfigure.properties.DruidStatProperties;
+import com.alibaba.druid.util.Utils;
+import org.springframework.boot.autoconfigure.AutoConfigureAfter;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
+import org.springframework.boot.web.servlet.FilterRegistrationBean;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+import javax.servlet.*;
+import java.io.IOException;
+
+@Configuration
+@AutoConfigureAfter(DruidDataSourceAutoConfigure.class)
+public class DruidConfig {
+
+ /**
+ * 带有广告的common.js全路径,druid-1.1.14
+ */
+ private static final String FILE_PATH = "support/http/resources/js/common.js";
+ /**
+ * 原始脚本,触发构建广告的语句
+ */
+ private static final String ORIGIN_JS = "this.buildFooter();";
+ /**
+ * 替换后的脚本
+ */
+ private static final String NEW_JS = "//this.buildFooter();";
+
+ /**
+ * 去除Druid监控页面的广告
+ *
+ * @param properties DruidStatProperties属性集合
+ * @return {@link org.springframework.boot.web.servlet.FilterRegistrationBean}
+ */
+ @Bean
+ @ConditionalOnWebApplication
+ @ConditionalOnProperty(name = "spring.datasource.druid.stat-view-servlet.enabled", havingValue = "true")
+ public FilterRegistrationBean removeDruidAdFilter(
+ DruidStatProperties properties) throws IOException {
+ // 获取web监控页面的参数
+ DruidStatProperties.StatViewServlet config = properties.getStatViewServlet();
+ // 提取common.js的配置路径
+ String pattern = config.getUrlPattern() != null ? config.getUrlPattern() : "/druid/*";
+ String commonJsPattern = pattern.replaceAll("\\*", "js/common.js");
+ // 获取common.js
+ String text = Utils.readFromResource(FILE_PATH);
+ // 屏蔽 this.buildFooter(); 不构建广告
+ final String newJs = text.replace(ORIGIN_JS, NEW_JS);
+ FilterRegistrationBean registration = new FilterRegistrationBean<>();
+ registration.setFilter(new RemoveAdFilter(newJs));
+ registration.addUrlPatterns(commonJsPattern);
+ return registration;
+ }
+
+ /**
+ * 删除druid的广告过滤器
+ *
+ * @author BBF
+ */
+ private class RemoveAdFilter implements Filter {
+
+ private final String newJs;
+
+ public RemoveAdFilter(String newJS) {
+ this.newJs = newJS;
+ }
+
+ @Override
+ public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
+ throws IOException, ServletException {
+ chain.doFilter(request, response);
+ // 重置缓冲区,响应头不会被重置
+ response.resetBuffer();
+ response.getWriter().write(newJs);
+ }
+ }
+}
diff --git a/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysOnlineController.java b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysOnlineController.java
new file mode 100644
index 00000000..8c7c1f2a
--- /dev/null
+++ b/jeecg-boot/jeecg-boot-module-system/src/main/java/org/jeecg/modules/system/controller/SysOnlineController.java
@@ -0,0 +1,128 @@
+package org.jeecg.modules.system.controller;
+
+import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
+import lombok.extern.slf4j.Slf4j;
+import org.apache.commons.lang.StringUtils;
+import org.apache.shiro.SecurityUtils;
+import org.jeecg.common.api.vo.Result;
+import org.jeecg.common.constant.CacheConstant;
+import org.jeecg.common.constant.CommonConstant;
+import org.jeecg.common.system.api.ISysBaseAPI;
+import org.jeecg.common.system.util.JwtUtil;
+import org.jeecg.common.system.vo.LoginUser;
+import org.jeecg.common.util.RedisUtil;
+import org.jeecg.common.util.oConvertUtils;
+import org.jeecg.modules.base.service.BaseCommonService;
+import org.jeecg.modules.system.service.ISysUserService;
+import org.jeecg.modules.system.vo.SysOnlineVO;
+import org.springframework.beans.BeanUtils;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.data.redis.core.RedisTemplate;
+import org.springframework.web.bind.annotation.*;
+
+import javax.annotation.Resource;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @Description: 在线用户
+ * @Author: chenli
+ * @Date: 2020-06-07
+ * @Version: V1.0
+ */
+@RestController
+@RequestMapping("/sys/online")
+@Slf4j
+public class SysOnlineController {
+
+ @Autowired
+ private RedisUtil redisUtil;
+
+ @Autowired
+ public RedisTemplate redisTemplate;
+
+ @Autowired
+ public ISysUserService userService;
+
+ @Autowired
+ private ISysBaseAPI sysBaseAPI;
+
+ @Resource
+ private BaseCommonService baseCommonService;
+
+ @RequestMapping(value = "/list", method = RequestMethod.GET)
+ public Result> list(@RequestParam(name="username", required=false) String username, @RequestParam(name="pageNo", defaultValue="1") Integer pageNo,
+ @RequestParam(name="pageSize", defaultValue="10") Integer pageSize) {
+ Collection keys = redisTemplate.keys(CommonConstant.PREFIX_USER_TOKEN + "*");
+ SysOnlineVO online;
+ List onlineList = new ArrayList();
+ for (String key : keys) {
+ online = new SysOnlineVO();
+ String token = (String) redisUtil.get(key);
+ if (!StringUtils.isEmpty(token)){
+ online.setToken(token);
+ LoginUser loginUser = sysBaseAPI.getUserByName(JwtUtil.getUsername(token));
+ BeanUtils.copyProperties(loginUser, online);
+ if (StringUtils.isNotEmpty(username)) {
+ if (StringUtils.equals(username, online.getUsername())) {
+ onlineList.add(online);
+ }
+ } else {
+ onlineList.add(online);
+ }
+ }
+ }
+
+ Page page = new Page(pageNo, pageSize);
+ int count = onlineList.size();
+ List pages = new ArrayList<>();
+ //计算当前页第一条数据的下标
+ int currId = pageNo>1 ? (pageNo-1)*pageSize:0;
+ for (int i=0; i> result = new Result>();
+ result.setSuccess(true);
+ result.setResult(page);
+ return result;
+ }
+
+ /**
+ * 强退用户
+ */
+ @RequestMapping(value = "/forceLogout",method = RequestMethod.POST)
+ public Result