diff --git a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Crawler/CrawlerController.cs b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Crawler/CrawlerController.cs
index a836544..d32e3e2 100644
--- a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Crawler/CrawlerController.cs
+++ b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Crawler/CrawlerController.cs
@@ -118,7 +118,6 @@ namespace ZR.Admin.WebApi.Controllers.Crawler
/// 查询条件
///
[HttpGet("task/list")]
- [ActionPermissionFilter(Permission = "crawler:list")]
public async Task GetCrawlerList([FromQuery] CrawlerConfigQueryDto query)
{
var result = await _taskService.GetCrawlerListAsync(query);
diff --git a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/DashboardController.cs b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/DashboardController.cs
index 893110b..c50ea0c 100644
--- a/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/DashboardController.cs
+++ b/server/admin/ZrAdminNetCore/ZR.Admin.WebApi/Controllers/Liveforum/DashboardController.cs
@@ -23,7 +23,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
///
///
[HttpGet("statistics")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetStatistics()
{
var response = _dashboardService.GetStatistics();
@@ -36,7 +35,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
/// 天数,默认7天
///
[HttpGet("userTrend")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetUserTrend([FromQuery] int days = 7)
{
var response = _dashboardService.GetUserTrend(days);
@@ -49,7 +47,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
/// 天数,默认7天
///
[HttpGet("contentTrend")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetContentTrend([FromQuery] int days = 7)
{
var response = _dashboardService.GetContentTrend(days);
@@ -62,7 +59,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
/// 数量,默认10条
///
[HttpGet("latestPosts")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetLatestPosts([FromQuery] int count = 10)
{
var response = _dashboardService.GetLatestPosts(count);
@@ -74,7 +70,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
///
///
[HttpGet("pendingItems")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetPendingItems()
{
var response = _dashboardService.GetPendingItems();
@@ -87,7 +82,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
/// 数量,默认10条
///
[HttpGet("hotPosts")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetHotPosts([FromQuery] int count = 10)
{
var response = _dashboardService.GetHotPosts(count);
@@ -100,7 +94,6 @@ namespace ZR.Admin.WebApi.Controllers.Liveforum
/// 数量,默认10条
///
[HttpGet("latestComments")]
- [ActionPermissionFilter(Permission = "dashboard:query")]
public IActionResult GetLatestComments([FromQuery] int count = 10)
{
var response = _dashboardService.GetLatestComments(count);
diff --git a/server/admin/ZrAdminNetCore/ZR.Vue/nginx.conf b/server/admin/ZrAdminNetCore/ZR.Vue/nginx.conf
index 70d4d06..158deba 100644
--- a/server/admin/ZrAdminNetCore/ZR.Vue/nginx.conf
+++ b/server/admin/ZrAdminNetCore/ZR.Vue/nginx.conf
@@ -3,6 +3,7 @@ server {
server_name localhost;
root /usr/share/nginx/html;
index index.html;
+ client_max_body_size 50m;
# 开启gzip压缩
gzip on;
diff --git a/server/admin/ZrAdminNetCore/ZR.Vue/src/utils/request.js b/server/admin/ZrAdminNetCore/ZR.Vue/src/utils/request.js
index 4096f2c..cf0908a 100644
--- a/server/admin/ZrAdminNetCore/ZR.Vue/src/utils/request.js
+++ b/server/admin/ZrAdminNetCore/ZR.Vue/src/utils/request.js
@@ -94,7 +94,7 @@ service.interceptors.response.use(
if (response.status == 404) {
message = `${response.config.url}接口404`
} else if (response.status == 403) {
- window.location.href = import.meta.env.VITE_APP_ROUTER_PREFIX + '401'
+ message = '没有权限访问该资源'
} else if (message == 'Network Error') {
message = '后端接口连接异常'
} else if (message.includes('timeout')) {
diff --git a/server/admin/ZrAdminNetCore/document/sqlserver/add_dashboard_permission.sql b/server/admin/ZrAdminNetCore/document/sqlserver/add_dashboard_permission.sql
new file mode 100644
index 0000000..3d6254c
--- /dev/null
+++ b/server/admin/ZrAdminNetCore/document/sqlserver/add_dashboard_permission.sql
@@ -0,0 +1,57 @@
+-- ==========================================
+-- 修复:添加 Dashboard 首页统计 + 爬虫列表权限
+-- 目标库:zradmindb(管理后台库)
+-- 说明:dashboard:query 权限未注册,crawler:list 未分配给非超管角色,
+-- 导致非超管用户登录后首页 403
+-- ==========================================
+
+-- 1. 创建 Dashboard 权限菜单(如果不存在)
+IF NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'dashboard:query')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'首页统计查询', 0, 0, '', '', 'F', 'dashboard:query', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ dashboard:query 权限菜单创建成功'
+END
+ELSE
+ PRINT N'⚠ dashboard:query 权限菜单已存在,跳过'
+
+-- 2. 为所有角色分配 dashboard:query 和 crawler:list
+DECLARE @MenuId INT;
+DECLARE @InsertedCount INT;
+
+-- 分配 dashboard:query
+SELECT @MenuId = menuId FROM sys_menu WHERE perms = 'dashboard:query';
+IF @MenuId IS NOT NULL
+BEGIN
+ INSERT INTO sys_role_menu (role_id, menu_id, Create_by, Create_time)
+ SELECT r.RoleId, @MenuId, 'admin', GETDATE()
+ FROM sys_role r
+ WHERE r.DelFlag = 0
+ AND NOT EXISTS (
+ SELECT 1 FROM sys_role_menu rm
+ WHERE rm.role_id = r.RoleId AND rm.menu_id = @MenuId
+ );
+ SET @InsertedCount = @@ROWCOUNT;
+ PRINT N'✓ 已为 ' + CAST(@InsertedCount AS NVARCHAR(10)) + N' 个角色分配 dashboard:query 权限'
+END
+
+-- 分配 crawler:list
+SELECT @MenuId = menuId FROM sys_menu WHERE perms = 'crawler:list';
+IF @MenuId IS NOT NULL
+BEGIN
+ INSERT INTO sys_role_menu (role_id, menu_id, Create_by, Create_time)
+ SELECT r.RoleId, @MenuId, 'admin', GETDATE()
+ FROM sys_role r
+ WHERE r.DelFlag = 0
+ AND NOT EXISTS (
+ SELECT 1 FROM sys_role_menu rm
+ WHERE rm.role_id = r.RoleId AND rm.menu_id = @MenuId
+ );
+ SET @InsertedCount = @@ROWCOUNT;
+ PRINT N'✓ 已为 ' + CAST(@InsertedCount AS NVARCHAR(10)) + N' 个角色分配 crawler:list 权限'
+END
+
+PRINT N'=========================================='
+PRINT N'执行完成,受影响用户需重新登录生效'
+PRINT N'正式环境执行后需重启管理后台容器清除缓存'
+PRINT N'=========================================='
diff --git a/server/admin/ZrAdminNetCore/document/sqlserver/add_missing_permissions.sql b/server/admin/ZrAdminNetCore/document/sqlserver/add_missing_permissions.sql
new file mode 100644
index 0000000..32410bb
--- /dev/null
+++ b/server/admin/ZrAdminNetCore/document/sqlserver/add_missing_permissions.sql
@@ -0,0 +1,123 @@
+-- ==========================================
+-- 修复:补充 v1.2.0 缺失的菜单权限注册
+-- 目标库:zradmindb(管理后台库)
+-- 说明:v1.2.0 新增的身份组、CDK解绑等功能,
+-- Controller 加了权限注解但未在 sys_menu 注册,
+-- 导致非超管用户即使勾了父菜单也无法使用子功能
+-- ==========================================
+
+-- ========== 1. 用户列表(menuId=1186)下补充身份组相关按钮权限 ==========
+
+IF NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'useridentitygroups:query')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'查看用户身份组', 1186, 10, '', '', 'F', 'useridentitygroups:query', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ useridentitygroups:query 创建成功'
+END
+
+IF NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'useridentitygroups:assign')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'分配用户身份组', 1186, 11, '', '', 'F', 'useridentitygroups:assign', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ useridentitygroups:assign 创建成功'
+END
+
+IF NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'useridentitygroups:batchAssign')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'批量分配身份组', 1186, 12, '', '', 'F', 'useridentitygroups:batchAssign', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ useridentitygroups:batchAssign 创建成功'
+END
+
+IF NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'tusers:unbind-cdk')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'解绑CDK', 1186, 13, '', '', 'F', 'tusers:unbind-cdk', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ tusers:unbind-cdk 创建成功'
+END
+
+-- ========== 2. 身份组管理下补充查询详情权限 ==========
+-- 先找到身份组管理的父菜单
+DECLARE @IdentityGroupsParentId INT;
+SELECT @IdentityGroupsParentId = menuId FROM sys_menu WHERE perms = 'identitygroups:list';
+
+IF @IdentityGroupsParentId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'identitygroups:query')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'身份组详情', @IdentityGroupsParentId, 5, '', '', 'F', 'identitygroups:query', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ identitygroups:query 创建成功'
+END
+
+-- ========== 3. CDK管理下补充解绑权限 ==========
+DECLARE @CdkParentId INT;
+SELECT @CdkParentId = menuId FROM sys_menu WHERE perms = 'cdk:list' AND menuType = 'F';
+-- CDK的父菜单应该是CDK管理页面
+SELECT @CdkParentId = parentId FROM sys_menu WHERE perms = 'cdk:list' AND menuType = 'F';
+
+IF @CdkParentId IS NOT NULL AND NOT EXISTS (SELECT 1 FROM sys_menu WHERE perms = 'cdk:unbind')
+BEGIN
+ INSERT INTO sys_menu (menuName, parentId, orderNum, path, component, menuType, perms, icon, status, isFrame, isCache, visible, Create_time)
+ VALUES (N'解绑CDK', @CdkParentId, 10, '', '', 'F', 'cdk:unbind', '', 0, 1, 0, '0', GETDATE());
+ PRINT N'✓ cdk:unbind 创建成功'
+END
+
+-- ========== 4. 身份组列表权限也加到用户列表下(用户列表页面需要加载身份组下拉) ==========
+-- identitygroups:list 已存在但可能不在用户列表的子菜单下
+-- 这里不重复创建,但需要确保角色有这个权限
+
+-- ========== 5. 自动为已有"用户列表"权限的角色分配新增的子权限 ==========
+PRINT N''
+PRINT N'>>> 为已有用户列表权限的角色自动分配新增子权限'
+
+-- 找到所有拥有 tusers:query 权限的角色
+DECLARE @TusersQueryMenuId INT;
+SELECT @TusersQueryMenuId = menuId FROM sys_menu WHERE perms = 'tusers:query';
+
+DECLARE @NewPerms TABLE (perms NVARCHAR(100));
+INSERT INTO @NewPerms VALUES
+ ('useridentitygroups:query'),
+ ('useridentitygroups:assign'),
+ ('useridentitygroups:batchAssign'),
+ ('tusers:unbind-cdk'),
+ ('identitygroups:list');
+
+DECLARE @perm NVARCHAR(100);
+DECLARE @menuId INT;
+DECLARE @cnt INT;
+
+DECLARE perm_cursor CURSOR FOR SELECT perms FROM @NewPerms;
+OPEN perm_cursor;
+FETCH NEXT FROM perm_cursor INTO @perm;
+
+WHILE @@FETCH_STATUS = 0
+BEGIN
+ SELECT @menuId = menuId FROM sys_menu WHERE perms = @perm;
+
+ IF @menuId IS NOT NULL
+ BEGIN
+ INSERT INTO sys_role_menu (role_id, menu_id, Create_by, Create_time)
+ SELECT DISTINCT rm.role_id, @menuId, 'admin', GETDATE()
+ FROM sys_role_menu rm
+ WHERE rm.menu_id = @TusersQueryMenuId
+ AND NOT EXISTS (
+ SELECT 1 FROM sys_role_menu rm2
+ WHERE rm2.role_id = rm.role_id AND rm2.menu_id = @menuId
+ );
+ SET @cnt = @@ROWCOUNT;
+ IF @cnt > 0
+ PRINT N'✓ ' + @perm + N': 已为 ' + CAST(@cnt AS NVARCHAR(10)) + N' 个角色分配'
+ END
+
+ FETCH NEXT FROM perm_cursor INTO @perm;
+END
+
+CLOSE perm_cursor;
+DEALLOCATE perm_cursor;
+
+PRINT N''
+PRINT N'=========================================='
+PRINT N'执行完成!'
+PRINT N'新增权限已挂到对应父菜单下,在角色管理中可以看到并勾选'
+PRINT N'已自动为拥有"用户列表查询"权限的角色分配新增子权限'
+PRINT N'受影响用户需重新登录生效'
+PRINT N'=========================================='