支持自动分页查询
This commit is contained in:
parent
6f5df23429
commit
ef9df7765f
|
|
@ -0,0 +1,259 @@
|
||||||
|
package com.ruoyi.framework.mybatis;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.sql.Connection;
|
||||||
|
import java.sql.PreparedStatement;
|
||||||
|
import java.sql.ResultSet;
|
||||||
|
import java.sql.SQLException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import javax.xml.bind.PropertyException;
|
||||||
|
import org.apache.ibatis.executor.ErrorContext;
|
||||||
|
import org.apache.ibatis.executor.ExecutorException;
|
||||||
|
import org.apache.ibatis.executor.statement.BaseStatementHandler;
|
||||||
|
import org.apache.ibatis.executor.statement.RoutingStatementHandler;
|
||||||
|
import org.apache.ibatis.executor.statement.StatementHandler;
|
||||||
|
import org.apache.ibatis.mapping.BoundSql;
|
||||||
|
import org.apache.ibatis.mapping.MappedStatement;
|
||||||
|
import org.apache.ibatis.mapping.ParameterMapping;
|
||||||
|
import org.apache.ibatis.mapping.ParameterMode;
|
||||||
|
import org.apache.ibatis.plugin.Interceptor;
|
||||||
|
import org.apache.ibatis.plugin.Intercepts;
|
||||||
|
import org.apache.ibatis.plugin.Invocation;
|
||||||
|
import org.apache.ibatis.plugin.Plugin;
|
||||||
|
import org.apache.ibatis.plugin.Signature;
|
||||||
|
import org.apache.ibatis.reflection.MetaObject;
|
||||||
|
import org.apache.ibatis.reflection.property.PropertyTokenizer;
|
||||||
|
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
|
||||||
|
import org.apache.ibatis.session.Configuration;
|
||||||
|
import org.apache.ibatis.type.TypeHandler;
|
||||||
|
import org.apache.ibatis.type.TypeHandlerRegistry;
|
||||||
|
import com.ruoyi.common.utils.StringUtils;
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
|
|
||||||
|
/**三
|
||||||
|
* 拦截需要分页SQL
|
||||||
|
*
|
||||||
|
* @author yangzz
|
||||||
|
*/
|
||||||
|
@Intercepts({ @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
|
||||||
|
public class ExecutorPageMethodInterceptor implements Interceptor
|
||||||
|
{
|
||||||
|
|
||||||
|
private static String dialect = ""; // 数据库方言
|
||||||
|
private static String pageSqlId = ""; // mapper.xml中需要拦截的ID(正则匹配)
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object intercept(Invocation ivk) throws Throwable
|
||||||
|
{
|
||||||
|
// TODO Auto-generated method stub
|
||||||
|
if (ivk.getTarget() instanceof RoutingStatementHandler)
|
||||||
|
{
|
||||||
|
RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
|
||||||
|
BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler,
|
||||||
|
"delegate");
|
||||||
|
MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate,
|
||||||
|
"mappedStatement");
|
||||||
|
|
||||||
|
if (mappedStatement.getId().matches(pageSqlId))
|
||||||
|
{ // 拦截需要分页的SQL
|
||||||
|
BoundSql boundSql = delegate.getBoundSql();
|
||||||
|
Object parameterObject = boundSql.getParameterObject();// 分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
|
||||||
|
if (parameterObject == null)
|
||||||
|
{
|
||||||
|
throw new NullPointerException("parameterObject尚未实例化!");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Connection connection = (Connection) ivk.getArgs()[0];
|
||||||
|
String sql = boundSql.getSql();
|
||||||
|
// String countSql = "select count(0) from (" + sql+ ") as tmp_count"; //记录统计
|
||||||
|
String countSql = "select count(0) from (" + sql + ") tmp_count"; // 记录统计 == oracle 加 as 报错(SQL
|
||||||
|
// command not properly ended)
|
||||||
|
PreparedStatement countStmt = connection.prepareStatement(countSql);
|
||||||
|
BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql,
|
||||||
|
boundSql.getParameterMappings(), parameterObject);
|
||||||
|
setParameters(countStmt, mappedStatement, countBS, parameterObject);
|
||||||
|
ResultSet rs = countStmt.executeQuery();
|
||||||
|
int count = 0;
|
||||||
|
if (rs.next())
|
||||||
|
{
|
||||||
|
count = rs.getInt(1);
|
||||||
|
}
|
||||||
|
rs.close();
|
||||||
|
countStmt.close();
|
||||||
|
// System.out.println(count);
|
||||||
|
PageUtilEntity pageUtilEntity = null;
|
||||||
|
if (parameterObject instanceof PageUtilEntity)
|
||||||
|
{ // 参数就是Page实体
|
||||||
|
pageUtilEntity = (PageUtilEntity) parameterObject;
|
||||||
|
pageUtilEntity.setEntityOrField(true);
|
||||||
|
pageUtilEntity.setTotalResult(count);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ // 参数为某个实体,该实体拥有Page属性
|
||||||
|
Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");
|
||||||
|
if (pageField != null)
|
||||||
|
{
|
||||||
|
pageUtilEntity = (PageUtilEntity) ReflectHelper.getValueByFieldName(parameterObject, "PageUtilEntity");
|
||||||
|
if (pageUtilEntity == null)
|
||||||
|
{
|
||||||
|
pageUtilEntity = new PageUtilEntity();
|
||||||
|
}
|
||||||
|
pageUtilEntity.setEntityOrField(false);
|
||||||
|
pageUtilEntity.setTotalResult(count);
|
||||||
|
ReflectHelper.setValueByFieldName(parameterObject, "page", pageUtilEntity); // 通过反射,对实体对象设置分页对象
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
throw new NoSuchFieldException(
|
||||||
|
parameterObject.getClass().getName() + "不存在 pageUtilEntity 属性!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
String pageSql = generatePageSql(sql, pageUtilEntity);
|
||||||
|
ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ivk.proceed();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler
|
||||||
|
*
|
||||||
|
* @param ps
|
||||||
|
* @param mappedStatement
|
||||||
|
* @param boundSql
|
||||||
|
* @param parameterObject
|
||||||
|
* @throws SQLException
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql,
|
||||||
|
Object parameterObject) throws SQLException
|
||||||
|
{
|
||||||
|
ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
|
||||||
|
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
|
||||||
|
if (parameterMappings != null)
|
||||||
|
{
|
||||||
|
Configuration configuration = mappedStatement.getConfiguration();
|
||||||
|
TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry();
|
||||||
|
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
|
||||||
|
for (int i = 0; i < parameterMappings.size(); i++)
|
||||||
|
{
|
||||||
|
ParameterMapping parameterMapping = parameterMappings.get(i);
|
||||||
|
if (parameterMapping.getMode() != ParameterMode.OUT)
|
||||||
|
{
|
||||||
|
Object value;
|
||||||
|
String propertyName = parameterMapping.getProperty();
|
||||||
|
PropertyTokenizer prop = new PropertyTokenizer(propertyName);
|
||||||
|
if (parameterObject == null)
|
||||||
|
{
|
||||||
|
value = null;
|
||||||
|
}
|
||||||
|
else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
|
||||||
|
{
|
||||||
|
value = parameterObject;
|
||||||
|
}
|
||||||
|
else if (boundSql.hasAdditionalParameter(propertyName))
|
||||||
|
{
|
||||||
|
value = boundSql.getAdditionalParameter(propertyName);
|
||||||
|
}
|
||||||
|
else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX)
|
||||||
|
&& boundSql.hasAdditionalParameter(prop.getName()))
|
||||||
|
{
|
||||||
|
value = boundSql.getAdditionalParameter(prop.getName());
|
||||||
|
if (value != null)
|
||||||
|
{
|
||||||
|
value = configuration.newMetaObject(value)
|
||||||
|
.getValue(propertyName.substring(prop.getName().length()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
value = metaObject == null ? null : metaObject.getValue(propertyName);
|
||||||
|
}
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
TypeHandler typeHandler = parameterMapping.getTypeHandler();
|
||||||
|
if (typeHandler == null)
|
||||||
|
{
|
||||||
|
throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName
|
||||||
|
+ " of statement " + mappedStatement.getId());
|
||||||
|
}
|
||||||
|
typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 根据数据库方言,生成特定的分页sql
|
||||||
|
*
|
||||||
|
* @param sql
|
||||||
|
* @param page
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String generatePageSql(String sql, PageUtilEntity pageUtilEntity)
|
||||||
|
{
|
||||||
|
if (pageUtilEntity != null && StringUtils.isNotEmpty(dialect))
|
||||||
|
{
|
||||||
|
StringBuffer pageSql = new StringBuffer();
|
||||||
|
if ("mysql".equals(dialect))
|
||||||
|
{
|
||||||
|
pageSql.append(sql);
|
||||||
|
pageSql.append(" limit " + pageUtilEntity.getPage() + "," + pageUtilEntity.getSize());
|
||||||
|
}
|
||||||
|
else if ("oracle".equals(dialect))
|
||||||
|
{
|
||||||
|
pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");
|
||||||
|
pageSql.append(sql);
|
||||||
|
// pageSql.append(") as tmp_tb where ROWNUM<=");
|
||||||
|
pageSql.append(") tmp_tb where ROWNUM<=");
|
||||||
|
pageSql.append(pageUtilEntity.getPage() + pageUtilEntity.getSize());
|
||||||
|
pageSql.append(") where row_id>");
|
||||||
|
pageSql.append(pageUtilEntity.getPage());
|
||||||
|
}
|
||||||
|
return pageSql.toString();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return sql;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object plugin(Object arg0)
|
||||||
|
{
|
||||||
|
return Plugin.wrap(arg0, this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setProperties(Properties p)
|
||||||
|
{
|
||||||
|
dialect = p.getProperty("dialect");
|
||||||
|
if (StringUtils.isEmpty(dialect))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw new PropertyException("dialect property is not found!");
|
||||||
|
}
|
||||||
|
catch (PropertyException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pageSqlId = p.getProperty("pageSqlId");
|
||||||
|
if (StringUtils.isEmpty(pageSqlId))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
throw new PropertyException("pageSqlId property is not found!");
|
||||||
|
}
|
||||||
|
catch (PropertyException e)
|
||||||
|
{
|
||||||
|
// TODO Auto-generated catch block
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,92 @@
|
||||||
|
package com.ruoyi.framework.mybatis;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 拦截需要分页SQL 反射工具
|
||||||
|
*
|
||||||
|
* @author yangzz
|
||||||
|
*/
|
||||||
|
public class ReflectHelper
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 获取obj对象fieldName的Field
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* @param fieldName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Field getFieldByFieldName(Object obj, String fieldName)
|
||||||
|
{
|
||||||
|
for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return superClass.getDeclaredField(fieldName);
|
||||||
|
}
|
||||||
|
catch (NoSuchFieldException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取obj对象fieldName的属性值
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* @param fieldName
|
||||||
|
* @return
|
||||||
|
* @throws SecurityException
|
||||||
|
* @throws NoSuchFieldException
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* @throws IllegalAccessException
|
||||||
|
*/
|
||||||
|
public static Object getValueByFieldName(Object obj, String fieldName)
|
||||||
|
throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
|
||||||
|
{
|
||||||
|
Field field = getFieldByFieldName(obj, fieldName);
|
||||||
|
Object value = null;
|
||||||
|
if (field != null)
|
||||||
|
{
|
||||||
|
if (field.isAccessible())
|
||||||
|
{
|
||||||
|
value = field.get(obj);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field.setAccessible(true);
|
||||||
|
value = field.get(obj);
|
||||||
|
field.setAccessible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置obj对象fieldName的属性值
|
||||||
|
*
|
||||||
|
* @param obj
|
||||||
|
* @param fieldName
|
||||||
|
* @param value
|
||||||
|
* @throws SecurityException
|
||||||
|
* @throws NoSuchFieldException
|
||||||
|
* @throws IllegalArgumentException
|
||||||
|
* @throws IllegalAccessException
|
||||||
|
*/
|
||||||
|
public static void setValueByFieldName(Object obj, String fieldName, Object value)
|
||||||
|
throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException
|
||||||
|
{
|
||||||
|
Field field = obj.getClass().getDeclaredField(fieldName);
|
||||||
|
if (field.isAccessible())
|
||||||
|
{
|
||||||
|
field.set(obj, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
field.setAccessible(true);
|
||||||
|
field.set(obj, value);
|
||||||
|
field.setAccessible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
package com.ruoyi.framework.web.controller;
|
package com.ruoyi.framework.web.controller;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.security.ShiroUtils;
|
import com.ruoyi.common.utils.security.ShiroUtils;
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
|
import com.ruoyi.framework.web.support.TableSupport;
|
||||||
import com.ruoyi.project.system.user.domain.User;
|
import com.ruoyi.project.system.user.domain.User;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -10,6 +12,15 @@ import com.ruoyi.project.system.user.domain.User;
|
||||||
*/
|
*/
|
||||||
public class BaseController
|
public class BaseController
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* 获取请求分页数据
|
||||||
|
*/
|
||||||
|
public PageUtilEntity getPageUtilEntity()
|
||||||
|
{
|
||||||
|
PageUtilEntity pageUtilEntity = TableSupport.buildPageRequest();
|
||||||
|
return pageUtilEntity;
|
||||||
|
}
|
||||||
|
|
||||||
public User getUser()
|
public User getUser()
|
||||||
{
|
{
|
||||||
return ShiroUtils.getUser();
|
return ShiroUtils.getUser();
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,15 @@
|
||||||
package com.ruoyi.framework.web.page;
|
package com.ruoyi.framework.web.page;
|
||||||
|
|
||||||
import java.util.Map;
|
import lombok.Data;
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 表格请求参数封装
|
* 表格请求参数封装
|
||||||
*
|
*
|
||||||
* @author yangzz
|
* @author yangzz
|
||||||
*/
|
*/
|
||||||
|
@Data
|
||||||
public class PageUtilEntity
|
public class PageUtilEntity
|
||||||
{
|
{
|
||||||
/** 总页数 */
|
|
||||||
private int totalPage;
|
|
||||||
/** 当前记录起始索引 */
|
/** 当前记录起始索引 */
|
||||||
private int page;
|
private int page;
|
||||||
/** 每页显示记录数 */
|
/** 每页显示记录数 */
|
||||||
|
|
@ -20,108 +18,10 @@ public class PageUtilEntity
|
||||||
private String orderByColumn;
|
private String orderByColumn;
|
||||||
/** 排序的方向 "desc" 或者 "asc". */
|
/** 排序的方向 "desc" 或者 "asc". */
|
||||||
private String isAsc;
|
private String isAsc;
|
||||||
/** 排序 */
|
|
||||||
protected String orderCond;
|
|
||||||
/** true:需要分页的地方,传入的参数就是Page实体;false:需要分页的地方,传入的参数所代表的实体拥有Page属性 */
|
/** true:需要分页的地方,传入的参数就是Page实体;false:需要分页的地方,传入的参数所代表的实体拥有Page属性 */
|
||||||
private boolean entityOrField;
|
private boolean entityOrField;
|
||||||
/** 总记录数 */
|
/** 总记录数 */
|
||||||
private int totalResult;
|
private int totalResult;
|
||||||
/** 请求参数 */
|
/** 搜索值 */
|
||||||
protected Map<String, String> relationMap;
|
private String searchValue;
|
||||||
|
|
||||||
public int getTotalPage()
|
|
||||||
{
|
|
||||||
return totalPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTotalPage(int totalPage)
|
|
||||||
{
|
|
||||||
this.totalPage = totalPage;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getPage()
|
|
||||||
{
|
|
||||||
return page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPage(int page)
|
|
||||||
{
|
|
||||||
this.page = page;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getSize()
|
|
||||||
{
|
|
||||||
return size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setSize(int size)
|
|
||||||
{
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrderByColumn()
|
|
||||||
{
|
|
||||||
return orderByColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrderByColumn(String orderByColumn)
|
|
||||||
{
|
|
||||||
this.orderByColumn = orderByColumn;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getIsAsc()
|
|
||||||
{
|
|
||||||
return isAsc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIsAsc(String isAsc)
|
|
||||||
{
|
|
||||||
this.isAsc = isAsc;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEntityOrField()
|
|
||||||
{
|
|
||||||
return entityOrField;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setEntityOrField(boolean entityOrField)
|
|
||||||
{
|
|
||||||
this.entityOrField = entityOrField;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getTotalResult()
|
|
||||||
{
|
|
||||||
return totalResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTotalResult(int totalResult)
|
|
||||||
{
|
|
||||||
this.totalResult = totalResult;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getOrderCond()
|
|
||||||
{
|
|
||||||
String orderCond = "";
|
|
||||||
if (StringUtils.isNotNull(orderByColumn) && StringUtils.isNotNull(isAsc))
|
|
||||||
{
|
|
||||||
orderCond = "ORDER BY " + this.orderByColumn + " " + this.isAsc;
|
|
||||||
}
|
|
||||||
return orderCond;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setOrderCond(String orderCond)
|
|
||||||
{
|
|
||||||
this.orderCond = orderCond;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Map<String, String> getRelationMap()
|
|
||||||
{
|
|
||||||
return relationMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRelationMap(Map<String, String> relationMap)
|
|
||||||
{
|
|
||||||
this.relationMap = relationMap;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
package com.ruoyi.framework.web.support;
|
||||||
|
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
import com.ruoyi.common.utils.HttpContextUtils;
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 表格数据处理
|
||||||
|
*
|
||||||
|
* @author yangzz
|
||||||
|
*/
|
||||||
|
public class TableSupport
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* 封装分页对象
|
||||||
|
*/
|
||||||
|
public static PageUtilEntity getPageUtilEntity()
|
||||||
|
{
|
||||||
|
HttpServletRequest request = HttpContextUtils.getHttpServletRequest();
|
||||||
|
PageUtilEntity pageUtilEntity = new PageUtilEntity();
|
||||||
|
pageUtilEntity.setPage(Integer.valueOf(request.getParameter("offset")));
|
||||||
|
pageUtilEntity.setSize(Integer.valueOf(request.getParameter("limit")));
|
||||||
|
pageUtilEntity.setOrderByColumn(request.getParameter("sort"));
|
||||||
|
pageUtilEntity.setIsAsc(request.getParameter("order"));
|
||||||
|
pageUtilEntity.setSearchValue(request.getParameter("search"));
|
||||||
|
return pageUtilEntity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PageUtilEntity buildPageRequest()
|
||||||
|
{
|
||||||
|
return getPageUtilEntity();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -4,18 +4,18 @@ import java.util.List;
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.stereotype.Controller;
|
import org.springframework.stereotype.Controller;
|
||||||
import org.springframework.ui.Model;
|
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
import org.springframework.web.bind.annotation.PathVariable;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestParam;
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.ResponseBody;
|
import org.springframework.web.bind.annotation.ResponseBody;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.StringUtils;
|
|
||||||
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
import com.ruoyi.framework.aspectj.lang.annotation.Log;
|
||||||
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
||||||
import com.ruoyi.framework.web.controller.BaseController;
|
import com.ruoyi.framework.web.controller.BaseController;
|
||||||
import com.ruoyi.framework.web.domain.JSON;
|
import com.ruoyi.framework.web.domain.JSON;
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
import com.ruoyi.framework.web.page.TableDataInfo;
|
import com.ruoyi.framework.web.page.TableDataInfo;
|
||||||
import com.ruoyi.project.monitor.online.domain.OnlineSession;
|
import com.ruoyi.project.monitor.online.domain.OnlineSession;
|
||||||
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
||||||
|
|
@ -46,39 +46,36 @@ public class UserOnlineController extends BaseController
|
||||||
|
|
||||||
@GetMapping("/list")
|
@GetMapping("/list")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public TableDataInfo list(Model model)
|
public TableDataInfo list()
|
||||||
{
|
{
|
||||||
List<UserOnline> list = userOnlineService.selectUserOnlines();
|
PageUtilEntity pageUtilEntity = this.getPageUtilEntity();
|
||||||
TableDataInfo tableDataInfo = new TableDataInfo(list, 111);
|
List<UserOnline> list = userOnlineService.pageInfoQueryUserOnline(pageUtilEntity);
|
||||||
|
TableDataInfo tableDataInfo = new TableDataInfo(list, pageUtilEntity.getTotalResult());
|
||||||
return tableDataInfo;
|
return tableDataInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@GetMapping("/forceLogout")
|
@Log(title = "监控管理", action = "在线用户-批量踢出用户")
|
||||||
|
@PostMapping("/batchForceLogout")
|
||||||
@ResponseBody
|
@ResponseBody
|
||||||
public JSON forceLogout(@RequestParam(value = "ids") String[] ids)
|
public JSON batchForceLogout(@RequestParam("ids[]") String[] ids)
|
||||||
{
|
{
|
||||||
try
|
for (String sessionId : ids)
|
||||||
{
|
{
|
||||||
for (String sessionId : ids)
|
UserOnline online = userOnlineService.selectByOnlineId(sessionId);
|
||||||
|
if (online == null)
|
||||||
{
|
{
|
||||||
UserOnline online = userOnlineService.selectByOnlineId(sessionId);
|
return JSON.error("用户已下线");
|
||||||
if (online == null)
|
|
||||||
{
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
userOnlineService.forceLogout(sessionId);
|
|
||||||
}
|
}
|
||||||
return JSON.ok();
|
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
|
||||||
}
|
if (onlineSession == null)
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
String msg = "未知错误";
|
|
||||||
if (StringUtils.isNotEmpty(e.getMessage()))
|
|
||||||
{
|
{
|
||||||
msg = e.getMessage();
|
return JSON.error("用户已下线");
|
||||||
}
|
}
|
||||||
return JSON.error(msg);
|
onlineSession.setStatus(OnlineSession.OnlineStatus.off_line);
|
||||||
|
online.setStatus(OnlineSession.OnlineStatus.off_line);
|
||||||
|
userOnlineService.saveByOnline(online);
|
||||||
}
|
}
|
||||||
|
return JSON.ok();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Log(title = "监控管理", action = "在线用户-踢出用户")
|
@Log(title = "监控管理", action = "在线用户-踢出用户")
|
||||||
|
|
@ -89,12 +86,12 @@ public class UserOnlineController extends BaseController
|
||||||
UserOnline online = userOnlineService.selectByOnlineId(sessionId);
|
UserOnline online = userOnlineService.selectByOnlineId(sessionId);
|
||||||
if (online == null)
|
if (online == null)
|
||||||
{
|
{
|
||||||
return JSON.error("用户已下线。数据不存在");
|
return JSON.error("用户已下线");
|
||||||
}
|
}
|
||||||
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
|
OnlineSession onlineSession = (OnlineSession) onlineSessionDAO.readSession(online.getSessionId());
|
||||||
if (onlineSession == null)
|
if (onlineSession == null)
|
||||||
{
|
{
|
||||||
return JSON.error("用户已下线。会话不存在");
|
return JSON.error("用户已下线");
|
||||||
}
|
}
|
||||||
onlineSession.setStatus(OnlineSession.OnlineStatus.off_line);
|
onlineSession.setStatus(OnlineSession.OnlineStatus.off_line);
|
||||||
online.setStatus(OnlineSession.OnlineStatus.off_line);
|
online.setStatus(OnlineSession.OnlineStatus.off_line);
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ package com.ruoyi.project.monitor.online.dao;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -38,10 +39,10 @@ public interface IUserOnlineDao
|
||||||
/**
|
/**
|
||||||
* 查询会话集合
|
* 查询会话集合
|
||||||
*
|
*
|
||||||
* @param online 会话信息
|
* @param pageUtilEntity 分页参数
|
||||||
* @return 会话集合
|
* @return 会话集合
|
||||||
*/
|
*/
|
||||||
public List<UserOnline> selectUserOnlines();
|
public List<UserOnline> pageInfoQuery(PageUtilEntity pageUtilEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 查询过期会话集合
|
* 查询过期会话集合
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,9 @@ package com.ruoyi.project.monitor.online.dao;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.springframework.stereotype.Repository;
|
import org.springframework.stereotype.Repository;
|
||||||
import com.ruoyi.framework.web.dao.DynamicObjectBaseDao;
|
import com.ruoyi.framework.web.dao.DynamicObjectBaseDao;
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 在线用户数据层
|
* 在线用户数据层
|
||||||
*
|
*
|
||||||
|
|
@ -52,15 +52,15 @@ public class UserOnlineDaoImpl extends DynamicObjectBaseDao implements IUserOnli
|
||||||
/**
|
/**
|
||||||
* 查询会话集合
|
* 查询会话集合
|
||||||
*
|
*
|
||||||
* @param online 会话信息
|
* @param pageUtilEntity 分页参数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<UserOnline> selectUserOnlines()
|
public List<UserOnline> pageInfoQuery(PageUtilEntity pageUtilEntity)
|
||||||
{
|
{
|
||||||
List<UserOnline> userOnlineList = null;
|
List<UserOnline> userOnlineList = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
userOnlineList = this.findForList("SystemOnlineMapper.selectUserOnlines");
|
userOnlineList = this.findForList("SystemOnlineMapper.pageInfoQueryUserOnline", pageUtilEntity);
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ package com.ruoyi.project.monitor.online.service;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -46,9 +47,10 @@ public interface IUserOnlineService
|
||||||
/**
|
/**
|
||||||
* 查询会话集合
|
* 查询会话集合
|
||||||
*
|
*
|
||||||
|
* @param pageUtilEntity 分页参数
|
||||||
* @return 会话集合
|
* @return 会话集合
|
||||||
*/
|
*/
|
||||||
public List<UserOnline> selectUserOnlines();
|
public List<UserOnline> pageInfoQueryUserOnline(PageUtilEntity pageUtilEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 读取Session信息
|
* 读取Session信息
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import com.ruoyi.common.utils.DateUtils;
|
import com.ruoyi.common.utils.DateUtils;
|
||||||
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
import com.ruoyi.framework.shiro.session.OnlineSessionDAO;
|
||||||
|
import com.ruoyi.framework.web.page.PageUtilEntity;
|
||||||
import com.ruoyi.project.monitor.online.dao.IUserOnlineDao;
|
import com.ruoyi.project.monitor.online.dao.IUserOnlineDao;
|
||||||
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
import com.ruoyi.project.monitor.online.domain.UserOnline;
|
||||||
|
|
||||||
|
|
@ -87,12 +88,12 @@ public class UserOnlineServiceImpl implements IUserOnlineService
|
||||||
/**
|
/**
|
||||||
* 查询会话集合
|
* 查询会话集合
|
||||||
*
|
*
|
||||||
* @param online 会话信息
|
* @param pageUtilEntity 分页参数
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public List<UserOnline> selectUserOnlines()
|
public List<UserOnline> pageInfoQueryUserOnline(PageUtilEntity pageUtilEntity)
|
||||||
{
|
{
|
||||||
return userOnlineDao.selectUserOnlines();
|
return userOnlineDao.pageInfoQuery(pageUtilEntity);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,8 @@ spring:
|
||||||
datasource:
|
datasource:
|
||||||
type: com.alibaba.druid.pool.DruidDataSource
|
type: com.alibaba.druid.pool.DruidDataSource
|
||||||
driverClassName: com.mysql.jdbc.Driver
|
driverClassName: com.mysql.jdbc.Driver
|
||||||
url: jdbc:mysql://10.213.24.45:3306/ry?useUnicode=true&characterEncoding=utf8
|
#url: jdbc:mysql://10.213.24.45:3306/ry?useUnicode=true&characterEncoding=utf8
|
||||||
#url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8
|
url: jdbc:mysql://localhost:3306/ry?useUnicode=true&characterEncoding=utf8
|
||||||
username: root
|
username: root
|
||||||
password: password
|
password: password
|
||||||
# 初始化大小,最小,最大
|
# 初始化大小,最小,最大
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,24 @@
|
||||||
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
|
||||||
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
"http://mybatis.org/dtd/mybatis-3-config.dtd">
|
||||||
<configuration>
|
<configuration>
|
||||||
|
|
||||||
<settings>
|
<settings>
|
||||||
<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->
|
<setting name="cacheEnabled" value="true" /> <!-- 全局映射器启用缓存 -->
|
||||||
<setting name="useGeneratedKeys" value="true" /> <!-- 允许 JDBC 支持自动生成主键 -->
|
<setting name="useGeneratedKeys" value="true" /> <!-- 允许 JDBC 支持自动生成主键 -->
|
||||||
<setting name="defaultExecutorType" value="REUSE" /> <!-- 配置默认的执行器 -->
|
<setting name="defaultExecutorType" value="REUSE" /> <!-- 配置默认的执行器 -->
|
||||||
<setting name="logImpl" value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
|
<setting name="logImpl" value="SLF4J" /> <!-- 指定 MyBatis 所用日志的具体实现 -->
|
||||||
</settings>
|
</settings>
|
||||||
|
|
||||||
|
<typeAliases>
|
||||||
|
<!-- 分页 -->
|
||||||
|
<typeAlias type="com.ruoyi.framework.web.page.PageUtilEntity" alias="PageUtilEntity"/>
|
||||||
|
</typeAliases>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<plugin interceptor="com.ruoyi.framework.mybatis.ExecutorPageMethodInterceptor">
|
||||||
|
<property name="dialect" value="mysql" />
|
||||||
|
<property name="pageSqlId" value=".*pageInfoQuery.*" />
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
|
||||||
</configuration>
|
</configuration>
|
||||||
|
|
|
||||||
|
|
@ -40,7 +40,7 @@ PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
|
||||||
delete from sys_user_online where sessionId = #{sessionId}
|
delete from sys_user_online where sessionId = #{sessionId}
|
||||||
</delete>
|
</delete>
|
||||||
|
|
||||||
<select id="selectUserOnlines" resultMap="UserOnlineResult">
|
<select id="pageInfoQueryUserOnline" parameterType="PageUtilEntity" resultMap="UserOnlineResult">
|
||||||
select * from sys_user_online
|
select * from sys_user_online
|
||||||
</select>
|
</select>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,6 @@
|
||||||
|
// 自定义分页处理 ruoyi
|
||||||
|
|
||||||
|
// 初始化表格
|
||||||
function initTable(_columns, _url) {
|
function initTable(_columns, _url) {
|
||||||
$('.bootstrap-table').bootstrapTable({
|
$('.bootstrap-table').bootstrapTable({
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
|
|
@ -30,6 +33,14 @@ function initTable(_columns, _url) {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 刷新
|
||||||
function refresh() {
|
function refresh() {
|
||||||
$('.bootstrap-table').bootstrapTable('refresh');
|
$('.bootstrap-table').bootstrapTable('refresh');
|
||||||
|
}
|
||||||
|
|
||||||
|
// 获取选中数组
|
||||||
|
function getIdSelections(_id) {
|
||||||
|
return $.map($('.bootstrap-table').bootstrapTable('getSelections'), function (row) {
|
||||||
|
return row[_id]
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
@ -63,34 +63,42 @@ $(function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
function forceLogout(id) {
|
function forceLogout(id) {
|
||||||
layer.confirm('确定要强制选中用户下线吗?', {
|
layer.confirm("确定要强制选中用户下线吗?",{icon: 3, title:'提示'},function(index){
|
||||||
btn: ['确定', '取消']
|
|
||||||
},
|
|
||||||
function() {
|
|
||||||
$.ajax({
|
$.ajax({
|
||||||
url: prefix + "/forceLogout/" + id,
|
url: prefix + "/forceLogout/" + id,
|
||||||
type: "post",
|
type: "post",
|
||||||
data: {
|
data: { 'id': id },
|
||||||
'id': id
|
|
||||||
},
|
|
||||||
success: function(r) {
|
success: function(r) {
|
||||||
if (r.code == 0) {
|
if (r.code == 0) {
|
||||||
layer.msg(r.msg);
|
layer.msg(r.msg, { icon: 1, time: 1000 });
|
||||||
refresh();
|
refresh();
|
||||||
} else {
|
} else {
|
||||||
layer.msg(r.msg);
|
layer.alert(r.msg, {icon: 2, title:"系统提示"});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTest()
|
function batchForceLogout() {
|
||||||
{
|
var rows = getIdSelections("sessionId");
|
||||||
alert("addTest");
|
if (rows.length == 0) {
|
||||||
|
layer.msg("请选择要删除的数据");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
layer.confirm("确认要删除选中的" + rows.length + "条数据吗?",{icon: 3, title:'提示'},function(index){
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
data: { "ids": rows },
|
||||||
|
url: prefix + '/batchForceLogout',
|
||||||
|
success: function(r) {
|
||||||
|
if (r.code == 0) {
|
||||||
|
layer.msg(r.msg, { icon: 1, time: 1000 });
|
||||||
|
refresh();
|
||||||
|
} else {
|
||||||
|
layer.alert(r.msg, {icon: 2, title:"系统提示"});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function batDelTest()
|
|
||||||
{
|
|
||||||
alert("batDelTest");
|
|
||||||
}
|
|
||||||
|
|
@ -13,7 +13,7 @@
|
||||||
<link href="/css/plugins/jqTreeGrid/jquery.treegrid.css" rel="stylesheet">
|
<link href="/css/plugins/jqTreeGrid/jquery.treegrid.css" rel="stylesheet">
|
||||||
<!--summernote css -->
|
<!--summernote css -->
|
||||||
<link href="/css/plugins/summernote/summernote-0.8.8.css" rel="stylesheet">
|
<link href="/css/plugins/summernote/summernote-0.8.8.css" rel="stylesheet">
|
||||||
<link href="css/animate.css" rel="stylesheet">
|
<link href="/css/animate.css" rel="stylesheet">
|
||||||
<link href="/css/plugins/chosen/chosen.css" rel="stylesheet">
|
<link href="/css/plugins/chosen/chosen.css" rel="stylesheet">
|
||||||
<link href="/css/style.css" rel="stylesheet">
|
<link href="/css/style.css" rel="stylesheet">
|
||||||
</head>
|
</head>
|
||||||
|
|
@ -36,7 +36,6 @@
|
||||||
<script src="/js/plugins/jqTreeGrid/jquery.treegrid.bootstrap3.js"></script>
|
<script src="/js/plugins/jqTreeGrid/jquery.treegrid.bootstrap3.js"></script>
|
||||||
<script src="/js/plugins/chosen/chosen.jquery.js"></script>
|
<script src="/js/plugins/chosen/chosen.jquery.js"></script>
|
||||||
<script src="/ajax/libs/layer/layer.min.js"></script>
|
<script src="/ajax/libs/layer/layer.min.js"></script>
|
||||||
<script src="/ruoyi/js/common.js?v=1.0.0"></script>
|
|
||||||
<!--summernote-->
|
<!--summernote-->
|
||||||
<script src="/js/plugins/summernote/summernote.js"></script>
|
<script src="/js/plugins/summernote/summernote.js"></script>
|
||||||
<script src="/js/plugins/summernote/summernote-zh-CN.min.js"></script>
|
<script src="/js/plugins/summernote/summernote-zh-CN.min.js"></script>
|
||||||
|
|
|
||||||
|
|
@ -127,6 +127,6 @@
|
||||||
<script src="/js/bootstrap.min.js"></script>
|
<script src="/js/bootstrap.min.js"></script>
|
||||||
<script src="/js/plugins/metisMenu/jquery.metisMenu.js"></script>
|
<script src="/js/plugins/metisMenu/jquery.metisMenu.js"></script>
|
||||||
<script src="/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
|
<script src="/js/plugins/slimscroll/jquery.slimscroll.min.js"></script>
|
||||||
<script src="/ruoyi/js/common.js?v=1.0.0"></script>
|
<script src="/ruoyi/js/index.js?v=1.0.0"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -5,13 +5,14 @@
|
||||||
<head th:include="include :: header"></head>
|
<head th:include="include :: header"></head>
|
||||||
<body class="gray-bg">
|
<body class="gray-bg">
|
||||||
<div class="wrapper wrapper-content">
|
<div class="wrapper wrapper-content">
|
||||||
|
|
||||||
<div class="btn-group hidden-xs" id="tableToolbar" role="group">
|
<div class="btn-group hidden-xs" id="tableToolbar" role="group">
|
||||||
<button type="button" class="btn btn-outline btn-default">
|
<!--
|
||||||
<i class="glyphicon glyphicon-plus" onclick="addTest();"></i>
|
<button type="button" class="btn btn-outline btn-default" th:onclick="'javascript:addTest()'">
|
||||||
|
<i class="glyphicon glyphicon-plus""></i>
|
||||||
</button>
|
</button>
|
||||||
<button type="button" class="btn btn-outline btn-default">
|
-->
|
||||||
<i class="glyphicon glyphicon-trash" onclick="batDelTest();"></i>
|
<button type="button" class="btn btn-outline btn-default" th:onclick="'javascript:batchForceLogout()'">
|
||||||
|
<i class="glyphicon glyphicon-trash""></i>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -23,6 +24,6 @@
|
||||||
<!-- <a shiro:hasPermission="system:user:list" href="#">测试菜单</a> -->
|
<!-- <a shiro:hasPermission="system:user:list" href="#">测试菜单</a> -->
|
||||||
<!-- <a shiro:hasRole="admin" href="#">测试角色</a> -->
|
<!-- <a shiro:hasRole="admin" href="#">测试角色</a> -->
|
||||||
<div th:include="include :: footer"></div>
|
<div th:include="include :: footer"></div>
|
||||||
<script type="text/javascript" src="/js/appjs/monitor/online/online.js"></script>
|
<script type="text/javascript" src="/ruoyi/monitor/online/online.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
Loading…
Reference in New Issue