12月30号管理端界面优化,前后端配置
This commit is contained in:
parent
ce0e27f9e7
commit
2c73d0c552
47
Zhibo/admin/sql/fix_home_menu_v2.sql
Normal file
47
Zhibo/admin/sql/fix_home_menu_v2.sql
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
-- ============================================
|
||||
-- 首页菜单修复脚本 v2
|
||||
-- 用于确保侧边栏"首页"菜单能正确跳转到主页
|
||||
-- ============================================
|
||||
|
||||
-- 1. 查看当前一级菜单(pid=0)
|
||||
SELECT id, pid, name, icon, component, menu_type, sort, is_show, is_delte
|
||||
FROM eb_system_menu
|
||||
WHERE pid = 0
|
||||
ORDER BY sort DESC, id ASC;
|
||||
|
||||
-- 2. 查看是否已存在首页相关菜单
|
||||
SELECT * FROM eb_system_menu
|
||||
WHERE name IN ('首页', '控制台', '主页')
|
||||
OR component IN ('/dashboard', '/home', '/home/index');
|
||||
|
||||
-- ============================================
|
||||
-- 修复方案:更新现有首页菜单的component为/dashboard
|
||||
-- ============================================
|
||||
|
||||
-- 方案A:如果首页菜单存在但component不正确,更新它
|
||||
UPDATE eb_system_menu
|
||||
SET component = '/dashboard'
|
||||
WHERE name IN ('首页', '控制台', '主页')
|
||||
AND (component IS NULL OR component = '' OR component = '/home' OR component = '/home/index');
|
||||
|
||||
-- 方案B:如果首页菜单不存在,插入新记录
|
||||
-- 注意:先执行上面的查询,确认首页菜单是否存在
|
||||
|
||||
-- 检查是否需要插入(如果不存在首页菜单)
|
||||
-- 如果上面的查询结果为空,执行以下插入语句:
|
||||
|
||||
-- 获取当前最大的菜单ID
|
||||
SELECT MAX(id) as max_id FROM eb_system_menu;
|
||||
|
||||
-- 插入首页菜单(sort=300 确保排在最前面)
|
||||
-- 注意:请根据实际情况修改id值,确保不与现有记录冲突
|
||||
/*
|
||||
INSERT INTO `eb_system_menu` (`id`, `pid`, `name`, `icon`, `perms`, `component`, `menu_type`, `sort`, `is_show`, `is_delte`, `create_time`, `update_time`)
|
||||
VALUES (700, 0, '首页', 'el-icon-s-home', 'admin:dashboard:index', '/dashboard', 'C', 300, 1, 0, NOW(), NOW());
|
||||
*/
|
||||
|
||||
-- 3. 验证修复结果
|
||||
SELECT id, pid, name, icon, component, menu_type, sort, is_show
|
||||
FROM eb_system_menu
|
||||
WHERE name IN ('首页', '控制台', '主页')
|
||||
OR component = '/dashboard';
|
||||
|
|
@ -159,6 +159,21 @@ export const constantRoutes = [
|
|||
},
|
||||
],
|
||||
},
|
||||
// 首页路由别名 - 兼容数据库菜单配置的 /home 路径
|
||||
{
|
||||
path: '/home',
|
||||
component: Layout,
|
||||
redirect: '/home/index',
|
||||
hidden: true,
|
||||
children: [
|
||||
{
|
||||
path: 'index',
|
||||
component: () => import('@/views/dashboard/index'),
|
||||
name: 'Home',
|
||||
meta: { title: '首页', icon: 'el-icon-s-home', isAffix: true },
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
path: '/setting/uploadPicture',
|
||||
component: () => import('@/components/uploadPicture/index.vue'),
|
||||
|
|
|
|||
|
|
@ -253,7 +253,15 @@ function replaceChildListWithChildren(data) {
|
|||
const children = replaceChildListWithChildren(item.childList);
|
||||
// 创建一个新的对象,将 childList 替换为 children
|
||||
const title = item.name;
|
||||
const path = item.component;
|
||||
let path = item.component;
|
||||
|
||||
// 特殊处理:如果是首页相关菜单,确保路径正确
|
||||
if (item.name === '首页' || item.name === '控制台' || item.name === '主页') {
|
||||
if (!path || path === '' || path === '/home' || path === '/home/index') {
|
||||
path = '/dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
children,
|
||||
|
|
@ -265,8 +273,24 @@ function replaceChildListWithChildren(data) {
|
|||
component: undefined,
|
||||
};
|
||||
}
|
||||
// 如果不存在 childList 字段,直接返回原对象
|
||||
return item;
|
||||
|
||||
// 如果不存在 childList 字段,处理叶子节点
|
||||
let path = item.component;
|
||||
|
||||
// 特殊处理:如果是首页相关菜单,确保路径正确
|
||||
if (item.name === '首页' || item.name === '控制台' || item.name === '主页') {
|
||||
if (!path || path === '' || path === '/home' || path === '/home/index') {
|
||||
path = '/dashboard';
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
...item,
|
||||
title: item.name,
|
||||
path: path,
|
||||
name: undefined,
|
||||
component: undefined,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,11 +8,19 @@
|
|||
</div>
|
||||
|
||||
<el-form :inline="true" :model="queryForm" size="small" class="mb20">
|
||||
<el-form-item label="状态">
|
||||
<el-select v-model="queryForm.status" placeholder="全部" clearable class="selWidth120">
|
||||
<el-option label="全部用户" value="" />
|
||||
<el-option label="仅在线" value="online" />
|
||||
<el-option label="仅离线" value="offline" />
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item label="搜索">
|
||||
<el-input v-model="queryForm.keyword" placeholder="昵称/手机号" clearable class="selWidth" />
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-button type="primary" @click="handleSearch">搜索</el-button>
|
||||
<el-button @click="handleReset">重置</el-button>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
|
||||
|
|
@ -80,7 +88,7 @@ export default {
|
|||
loading: false,
|
||||
tableData: [],
|
||||
total: 0,
|
||||
queryForm: { keyword: '', page: 1, limit: 20 }
|
||||
queryForm: { keyword: '', status: '', page: 1, limit: 20 }
|
||||
};
|
||||
},
|
||||
mounted() {
|
||||
|
|
@ -95,6 +103,7 @@ export default {
|
|||
this.total = res.total || 0;
|
||||
} catch (error) {
|
||||
console.error('获取在线用户失败:', error);
|
||||
this.$message.error('获取用户列表失败');
|
||||
} finally {
|
||||
this.loading = false;
|
||||
}
|
||||
|
|
@ -103,6 +112,10 @@ export default {
|
|||
this.queryForm.page = 1;
|
||||
this.getList();
|
||||
},
|
||||
handleReset() {
|
||||
this.queryForm = { keyword: '', status: '', page: 1, limit: 20 };
|
||||
this.getList();
|
||||
},
|
||||
handleSizeChange(val) {
|
||||
this.queryForm.limit = val;
|
||||
this.getList();
|
||||
|
|
@ -129,6 +142,7 @@ export default {
|
|||
.header-row { display: flex; justify-content: space-between; align-items: center; margin-bottom: 20px; }
|
||||
.page-title { font-size: 18px; color: #303133; margin: 0; }
|
||||
.selWidth { width: 200px; }
|
||||
.selWidth120 { width: 120px; }
|
||||
.mb20 { margin-bottom: 20px; }
|
||||
.mt20 { margin-top: 20px; }
|
||||
.user-info { display: flex; align-items: center; gap: 12px; }
|
||||
|
|
|
|||
|
|
@ -96,27 +96,39 @@ public class MonitorController {
|
|||
|
||||
/**
|
||||
* 在线用户列表
|
||||
* 显示所有用户,按最后登录时间排序,标记在线状态(5分钟内活跃为在线)
|
||||
*/
|
||||
@ApiOperation(value = "在线用户列表")
|
||||
@GetMapping("/users")
|
||||
public CommonResult<CommonPage<Map<String, Object>>> getOnlineUsers(
|
||||
@RequestParam(value = "keyword", required = false) String keyword,
|
||||
@RequestParam(value = "status", required = false) String status,
|
||||
@RequestParam(value = "page", defaultValue = "1") Integer page,
|
||||
@RequestParam(value = "limit", defaultValue = "20") Integer limit) {
|
||||
|
||||
// 获取最近活跃的用户(5分钟内有登录记录)
|
||||
// 获取用户列表,按最后登录时间排序
|
||||
StringBuilder sql = new StringBuilder();
|
||||
sql.append("SELECT u.uid as id, u.nickname, u.avatar, u.phone, ");
|
||||
sql.append("u.last_login_time, u.create_time, ");
|
||||
sql.append("CASE WHEN u.last_login_time >= DATE_SUB(NOW(), INTERVAL 5 MINUTE) THEN 1 ELSE 0 END as is_online, ");
|
||||
sql.append("TIMESTAMPDIFF(MINUTE, u.last_login_time, NOW()) as inactive_minutes ");
|
||||
sql.append("FROM eb_user u ");
|
||||
sql.append("WHERE u.status = 1 ");
|
||||
sql.append("AND u.last_login_time >= DATE_SUB(NOW(), INTERVAL 30 MINUTE) ");
|
||||
|
||||
StringBuilder countSql = new StringBuilder();
|
||||
countSql.append("SELECT COUNT(*) FROM eb_user u ");
|
||||
countSql.append("WHERE u.status = 1 ");
|
||||
countSql.append("AND u.last_login_time >= DATE_SUB(NOW(), INTERVAL 30 MINUTE) ");
|
||||
|
||||
// 根据状态筛选:online=仅在线,offline=仅离线,空=全部
|
||||
if ("online".equals(status)) {
|
||||
String condition = " AND u.last_login_time >= DATE_SUB(NOW(), INTERVAL 5 MINUTE) ";
|
||||
sql.append(condition);
|
||||
countSql.append(condition);
|
||||
} else if ("offline".equals(status)) {
|
||||
String condition = " AND (u.last_login_time IS NULL OR u.last_login_time < DATE_SUB(NOW(), INTERVAL 5 MINUTE)) ";
|
||||
sql.append(condition);
|
||||
countSql.append(condition);
|
||||
}
|
||||
|
||||
if (keyword != null && !keyword.isEmpty()) {
|
||||
String condition = " AND (u.nickname LIKE '%" + keyword + "%' OR u.phone LIKE '%" + keyword + "%') ";
|
||||
|
|
@ -124,7 +136,8 @@ public class MonitorController {
|
|||
countSql.append(condition);
|
||||
}
|
||||
|
||||
sql.append(" ORDER BY u.last_login_time DESC ");
|
||||
// 优先显示在线用户,然后按最后登录时间排序
|
||||
sql.append(" ORDER BY is_online DESC, u.last_login_time DESC ");
|
||||
|
||||
Long total = jdbcTemplate.queryForObject(countSql.toString(), Long.class);
|
||||
|
||||
|
|
@ -135,10 +148,23 @@ public class MonitorController {
|
|||
|
||||
// 添加在线状态
|
||||
list.forEach(item -> {
|
||||
Integer inactiveMinutes = (Integer) item.get("inactive_minutes");
|
||||
item.put("isOnline", inactiveMinutes != null && inactiveMinutes < 5);
|
||||
Object inactiveObj = item.get("inactive_minutes");
|
||||
Long inactiveMinutes = null;
|
||||
if (inactiveObj instanceof Long) {
|
||||
inactiveMinutes = (Long) inactiveObj;
|
||||
} else if (inactiveObj instanceof Integer) {
|
||||
inactiveMinutes = ((Integer) inactiveObj).longValue();
|
||||
}
|
||||
// 5分钟内活跃视为在线
|
||||
boolean isOnline = inactiveMinutes != null && inactiveMinutes < 5;
|
||||
item.put("isOnline", isOnline);
|
||||
item.put("lastLoginTime", item.get("last_login_time"));
|
||||
item.put("createTime", item.get("create_time"));
|
||||
// 移除不需要的字段
|
||||
item.remove("is_online");
|
||||
item.remove("inactive_minutes");
|
||||
item.remove("last_login_time");
|
||||
item.remove("create_time");
|
||||
});
|
||||
|
||||
CommonPage<Map<String, Object>> result = new CommonPage<>();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user