新增 SportsHall/BatchDeleteClasses 接口:校验批量数量、本校运动馆班级归属及空班条件,在可串行化事务中清理班级和教练关联,并发送物联网删除同步。 学生批量删除增加 BatchDelete 动作权限校验;按实际页面菜单匹配权限,兼容生产库中重复的学生管理菜单。运动馆班级删除由已授权角色使用,不硬编码学校角色。 新增幂等菜单权限脚本,仅向学生管理和运动馆班级管理的有效页面菜单登记批量删除动作,不自动给角色授权。QA 与生产库已核验菜单动作;代码上线仍需独立部署。 验证:Debug/Release 构建通过,SQL 在 QA 重跑无重复写入。
50 lines
1.7 KiB
Transact-SQL
50 lines
1.7 KiB
Transact-SQL
SET XACT_ABORT ON;
|
|
BEGIN TRANSACTION;
|
|
|
|
DECLARE @menuUrl nvarchar(100);
|
|
DECLARE @menuId int;
|
|
DECLARE menu_cursor CURSOR LOCAL FAST_FORWARD FOR
|
|
SELECT Url FROM (VALUES (N'/studentsManage'), (N'/sportsHallClass')) AS menus(Url);
|
|
|
|
OPEN menu_cursor;
|
|
FETCH NEXT FROM menu_cursor INTO @menuUrl;
|
|
WHILE @@FETCH_STATUS = 0
|
|
BEGIN
|
|
IF (SELECT COUNT(*) FROM Sys_Menu
|
|
WHERE Url = @menuUrl AND ParentId > 0 AND MenuType = 0 AND Enable IN (1, 2)) <> 1
|
|
THROW 51001, N'页面菜单不存在或不唯一,请检查菜单配置', 1;
|
|
|
|
SELECT @menuId = Menu_Id FROM Sys_Menu
|
|
WHERE Url = @menuUrl AND ParentId > 0 AND MenuType = 0 AND Enable IN (1, 2);
|
|
|
|
IF EXISTS (SELECT 1 FROM Sys_Menu WHERE Menu_Id = @menuId
|
|
AND NULLIF(LTRIM(RTRIM(Auth)), N'') IS NOT NULL
|
|
AND (ISJSON(Auth) <> 1 OR LEFT(LTRIM(Auth), 1) <> N'['))
|
|
THROW 51002, N'菜单权限不是有效 JSON 数组,请先检查原始数据', 1;
|
|
|
|
UPDATE Sys_Menu
|
|
SET Auth = COALESCE(NULLIF(Auth, N''), N'[]')
|
|
WHERE Menu_Id = @menuId AND (Auth IS NULL OR Auth = N'');
|
|
|
|
UPDATE menu
|
|
SET Auth = JSON_MODIFY(menu.Auth, 'append $',
|
|
JSON_QUERY(N'{"text":"批量删除","value":"BatchDelete"}'))
|
|
FROM Sys_Menu AS menu
|
|
WHERE menu.Menu_Id = @menuId
|
|
AND NOT EXISTS (SELECT 1 FROM OPENJSON(menu.Auth)
|
|
WITH (Value nvarchar(100) '$.value') AS action
|
|
WHERE action.Value = N'BatchDelete');
|
|
|
|
FETCH NEXT FROM menu_cursor INTO @menuUrl;
|
|
END;
|
|
CLOSE menu_cursor;
|
|
DEALLOCATE menu_cursor;
|
|
|
|
COMMIT TRANSACTION;
|
|
|
|
SELECT MenuName, Url, Auth
|
|
FROM Sys_Menu
|
|
WHERE Url IN (N'/studentsManage', N'/sportsHallClass')
|
|
AND ParentId > 0 AND MenuType = 0;
|
|
GO
|