zoujiajian 14 godzin temu
rodzic
commit
178880536a

+ 8 - 0
docs/frontend-security-integration.md

@@ -172,3 +172,11 @@ ip 筛选目前只精确匹配 remoteIp 或 realIp,不查询 forwardedFor 链
 4. 余额金额为 0、负数、小数、超过 10 位或备注为空时拒绝;合法请求金额和流水一致,余额竞争更新失败时不产生流水。
 5. 修改优惠券同时提交伪造 createdTime,确认原创建时间不变。
 6. 执行 SQL、部署后重新登录刷新权限;历史异常优惠券/兑换码不会因部署自动作废,需要单独核查处理。
+
+## 登录日志菜单权限(2026-10-21 更新)
+- 入口改为系统管理下的登录日志,移除顶部快捷按钮。
+- 路由 `/setting/loginAudit`,旧地址 `/security/login-audit` 保留别名。
+- 查询接口 `GET /manage/login/audit/get` 由 root 限制改为登录且持有 `loginAudit:view`;响应格式不变。
+- 前端路由、页面和请求拦截同步校验该权限。该权限可查询全部登录日志,应仅授权可信审计人员。
+- 执行 `docs/sql/20261021-login-audit-menu.sql`,核对系统管理父菜单 ID;仅默认授权 root,其他角色手工勾选菜单并刷新权限、重新登录。
+- 验收:授权角色可查询;无权限角色无法进入且直接调用接口被拒绝;未登录拒绝;旧地址同样受控。

+ 8 - 4
docs/sql/20261021-coupon-exchange-permissions.sql

@@ -4,8 +4,12 @@
 -- 不创建前端路由,不改已有权限,不给普通角色扩权。
 SET @coupon_parent_override = NULL;
 SET @exchange_parent_override = NULL;
--- Set this to the actual user-management menu ID before running balance grants.
+-- 自动识别用户列表;匹配不唯一时填写实际用户列表菜单 ID。
 SET @balance_parent_override = NULL;
+SET @balance_parent = COALESCE(@balance_parent_override, (
+    SELECT CASE WHEN COUNT(*) = 1 THEN MIN(id) ELSE NULL END
+    FROM cms_menu WHERE type = 'menu' AND (title = '用户列表' OR path = '/userManage/user')
+));
 
 SET @coupon_parent = COALESCE(@coupon_parent_override, (
     SELECT CASE WHEN COUNT(*) = 1 THEN MIN(id) ELSE NULL END
@@ -33,9 +37,9 @@ INSERT INTO tmp_coupon_exchange_permissions VALUES
 ('兑换码生成', 'exchangeCode:add', @exchange_parent, 2),
 ('兑换码导出', 'exchangeCode:export', @exchange_parent, 3),
 ('兑换码退款重发', 'exchangeCode:refund', @exchange_parent, 4),
-('增加用户余额', 'userBalance:add', @balance_parent_override, 1),
-('扣除用户余额', 'userBalance:deduct', @balance_parent_override, 2),
-('余额操作记录', 'userBalance:view', @balance_parent_override, 3);
+('增加用户余额', 'userBalance:add', @balance_parent, 1),
+('扣除用户余额', 'userBalance:deduct', @balance_parent, 2),
+('余额操作记录', 'userBalance:view', @balance_parent, 3);
 
 START TRANSACTION;
 INSERT INTO cms_menu

+ 2 - 2
netflix-web/src/main/java/com/cyksj/web/controller/manage/LoginAuditController.java

@@ -1,7 +1,7 @@
 package com.cyksj.web.controller.manage;
 
 import cn.dev33.satoken.annotation.SaCheckLogin;
-import cn.dev33.satoken.annotation.SaCheckRole;
+import cn.dev33.satoken.annotation.SaCheckPermission;
 import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
 import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
 import com.cyksj.common.exception.BusinessRuntimeException;
@@ -17,7 +17,7 @@ import java.util.Date;
 @RestController
 @RequestMapping("/manage/login/audit")
 @SaCheckLogin
-@SaCheckRole("root")
+@SaCheckPermission("loginAudit:view")
 @RequiredArgsConstructor
 public class LoginAuditController {
     private final LoginAuditMapper mapper;