当前位置: 首页
AI教程
AI从零搭建用户权限系统的完整过程记录

AI从零搭建用户权限系统的完整过程记录

热心网友 时间:2026-07-11
转载

基于Vue、Java17、SpringBoot3和MySQL,利用AI从空白仓库搭建RBAC权限系统,涵盖用户登录、用户 角色 权限管理及审计日志。通过CLAUDE md制定技术栈和规范,分阶段生成数据模型、AOP权限拦截器、Service层和审计日志,需多次调整以对齐技术栈。

从零搭建用户权限系统:AI全流程开发实录

从一个刚完成初始化的空白代码仓库起步,借助AI完整构建一套RBAC权限管理系统。前端采用Vue,后端基于Java 17与Spring Boot 3,数据库选用MySQL,认证机制使用SaToken。功能需求涵盖:用户登录、用户管理、角色管理、权限分配、操作审计日志。

我让 AI 从零做了一个用户权限系统,这是全过程记录

放在以往,这套任务需要手动编写好几天:设计数据库表结构、编写实体类、构建Service层与Controller层、撰写单元测试,随后进行代码审查和缺陷修复。这次决定换一种方式——让Claude从需求分析到代码生成完整走一遍,同时验证此前文章中总结的规则管理方法,在实际项目中究竟是否好用。

第一阶段:明确需求目标

接手这类需求时,一上来就让AI直接写代码是大忌。凡是涉及3个以上文件需要改动的任务,先使用/plan指令让AI输出规划方案——这是此前反复踩坑后总结出的经验。曾经因为中途发现方向偏差,整个上下文作废只能重来,这种情况至少遇到过两次。

先让Claude读取项目现有代码结构,随后明确需求:

/plan 这是一个AI开发RBAC系统的示例,目前处于刚初始化仓库、尚未进行任何开发的状态。前端使用Vue,后端采用Java 17,数据库使用MySQL。需要实现用户登录、用户管理与权限管理功能。RBAC权限系统的具体要求:
- 支持用户多角色分配
- 实现基于角色的细粒度权限控制
- 权限校验使用AOP拦截,不在每个方法中手写
- 角色和权限变更必须记录审计日志
- 数据库使用MySQL

AI给出的方案对比了三种实现路径:

  1. 基于角色的RBAC——用户关联角色,角色关联权限点
  2. 基于策略的模式——每个权限定义一个策略类
  3. 基于表达式语言的SpEL——使用Spring Expression Language编写权限表达式

最终选择了第一种。RBAC属于标准方案,SaToken原生支持角色与权限判断,团队接手也更容易。后两种虽然更灵活,但学习和维护成本显著增加。

方案确认后,Claude将其拆解为按依赖关系排序的任务清单:

1. 设计数据模型(User-Role-Permission 五张关系表)
2. 编写实体类和Mapper(MyBatis-Plus)
3. 编写Service层(权限校验、角色分配)
4. 编写AOP拦截器(基于注解的权限校验)
5. 编写Controller(用户/角色/权限CRUD)
6. 实现审计日志
7. 编写全局异常处理

这份任务清单,就是后续整个开发过程的“施工蓝图”。

第二阶段:制定规则

这次没有采用三层规则分层,仅使用一个CLAUDE.md文件。原因很简单——这个权限模块属于一次性开发任务,并非需要长期维护的独立子系统。专门为其建立L3文件,后期维护成本会超过收益。CLAUDE.md中的核心规则:

## 技术栈
- Java 17, Spring Boot 3.x
- MyBatis-Plus 3.5.x, SaToken 1.38.x
- Hutool 5.8.x, Lombok 1.18.x
## 代码规范
- 使用 @RequirePermission 注解 + AOP 进行权限校验
- 禁止在 Controller 方法体内编写权限判断逻辑
- 使用 BusinessException 抛出业务异常
- 统一使用 ApiResponse 包装返回结果
## 查询规范
- 使用 MyBatis-Plus LambdaQueryWrapper
- 禁止手写 SQL 字符串拼接

核心原则只有一条:如果你不把规则说清楚,AI就会按照它的训练数据来生成代码。而训练数据来源于全网代码的平均水平,并非你团队的规范。

第三阶段:正式编写代码

数据模型设计

先运行/init让Claude确认项目结构,然后从任务1开始。RBAC的标准数据模型包含5张表:

┌─────────┐┌──────────────┐ ┌─────────┐
│t_user │ ────▶│ t_user_role│◀────│ t_role│
│(用户)││(用户-角色)│ │(角色)│
└─────────┘└──────────────┘ └────┬────┘
                                  │
                          ┌─────────────────┐
                          │t_role_permission│
                          │ (角色-权限)│
                          └─────────────────┘
                                  │
                          ┌──────┴─────┐
                          │t_permission│
                          │ (权限)│
                          └────────────┘

Claude生成的实体类采用MyBatis-Plus注解,而非JPA——这也得益于在CLAUDE.md中提前明确了技术栈:

@Data
@TableName("user_role")
public class UserRole {
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField("user_id")
    private Long userId;
    @TableField("role_id")
    private Long roleId;
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
}

使用MyBatis-Plus的好处在于无需操心EAGER/LAZY等JPA加载策略——每次查询都是主动调用,N+1问题通过手动优化查询逻辑来避免。

AOP权限拦截器

这一部分是权限系统的核心。@RequirePermission注解的设计十分简洁:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequirePermission {
    /** * 权限标识,格式为 "resource:action" */
    String value();
}

切面实现:

@Slf4j
@Aspect
@Component
@RequiredArgsConstructor
public class PermissionAspect {
    private final PermissionService permissionService;
    @Around("@annotation(requirePermission)")
    public Object checkPermission(ProceedingJoinPoint joinPoint,
                                  RequirePermission requirePermission) throws Throwable {
        if (!StpUtil.isLogin()) {
            throw new PermissionDeniedException("未登录或登录已过期");
        }
        String permissionCode = requirePermission.value();
        long userId = StpUtil.getLoginIdAsLong();
        boolean hasPermission = permissionService.hasPermission(userId, permissionCode);
        if (!hasPermission) {
            log.warn("用户 {} 尝试访问权限 {} 被拒绝", userId, permissionCode);
            throw new PermissionDeniedException("没有权限执行此操作");
        }
        return joinPoint.proceed();
    }
}

使用方法就是在Controller方法上添加注解:

@RequirePermission("role:create")
@PostMapping
public ApiResponse createRole(@Valid @RequestBody CreateRoleRequest request) {
    Role role = roleService.createRole(request);
    auditLogService.logAudit(...);
    return ApiResponse.success(role);
}

这一部分Claude生成的质量非常高——AOP结合自定义注解是Spring生态中的标准模式,训练数据中的样本充足。而且使用了SaToken的StpUtil.isLogin()进行登录检查,说明AI确实读取了项目中的依赖配置。

权限校验的Service层

这里是第一个值得深入讨论的地方。AI生成的hasPermission方法:

@Override
public boolean hasPermission(Long userId, String permissionCode) {
    // 获取用户所有角色
    List roleCodes = userRoleService.getUserRoleCodes(userId);
    if (roleCodes.isEmpty()) {
        return false;
    }
    // 获取用户所有角色的权限
    List userPermissions = getUserPermissionCodes(userId);
    return userPermissions.contains(permissionCode);
}

接着是getUserPermissionCodes的具体实现:

@Override
public List getUserPermissionCodes(Long userId) {
    List roles = userRoleService.getUserRoles(userId);
    if (CollUtil.isEmpty(roles)) {
        return List.of();
    }
    Set permissions = new HashSet<>();
    for (Role role : roles) {
        if (role.getStatus() != 1) continue;
        List permissionIds = rolePermissionService.getPermissionIdsByRoleId(role.getId());
        if (!permissionIds.isEmpty()) {
            List perms = listByIds(permissionIds);
            perms.stream().filter(p -> p.getStatus() == 1)
                 .map(Permission::getCode)
                 .forEach(permissions::add);
        }
    }
    return List.copyOf(permissions);
}

这段代码实际上存在N+1查询问题。对每个角色都会调用getPermissionIdsByRoleId,再对每个角色调用listByIds批量查询权限。如果用户有3个角色,就需要执行6次数据库查询(3次查询权限ID + 3次批量查询权限详情)。不过这个项目属于个人演示性质,数据量较小,暂时无需优化。如果放到真实生产环境,应当改为一次JOIN查询或使用IN子句批量查询——这也印证了此前文章中提到的观点:AI不会主动考虑数据量增长后的性能问题。

审计日志

关于审计日志,AI最初的方案是使用AOP切面自动记录,后来改为在Controller中手动调用auditLogService.logAudit()。原因在于:AOP切面虽然看起来省事,但很难记录变更前后的具体数值。例如“将用户从'普通用户'改为'管理员'”这类信息,AOP只能获取方法名和参数,无法拿到变更前的数据。手动调用虽然多写几行代码,但记录的精准度更高。审计日志使用的AuditLog实体:

@Data
@TableName("audit_log")
public class AuditLog {
    @TableId(type = IdType.AUTO)
    private Long id;
    @TableField("operator_id")
    private Long operatorId;
    @TableField("operator_name")
    private String operatorName;
    @TableField("action")
    private String action;
    @TableField("target_type")
    private String targetType;
    @TableField("target_id")
    private Long targetId;
    @TableField("detail")
    private String detail;
    @TableField("ip_address")
    private String ipAddress;
    @TableField(value = "create_time", fill = FieldFill.INSERT)
    private LocalDateTime createTime;
}

Controller中的调用方式:

auditLogService.logAudit(
    StpUtil.getLoginIdAsLong(),
    StpUtil.getLoginIdAsString(),
    AuditAction.CREATE_ROLE.name(),
    "role",
    role.getId(),
    "创建角色: " + role.getName(),
    null
);

AI开发很少一次通过

这套权限模块的代码,从写完到能正常运行,中间经过了多个回合的调整。这其实很正常——使用AI编写代码时,一次需求描述清楚、AI一次写完、一次审查通过的情况非常罕见。原因也很简单:AI不会主动考虑边界场景。你让它“做一套RBAC权限系统”,它会给出一个标准RBAC实现,但标准实现并不一定适合你的具体场景。

本次主要的反复集中在以下几个问题上:

技术栈对齐

最初AI生成的代码混用了JPA和MyBatis-Plus两种ORM——部分实体使用了@Entity,部分使用了@TableName。原因是在最初的CLAUDE.md中没有明确说明技术栈,AI按照训练数据的默认倾向选择了JPA(Spring Boot教程中JPA出现频率较高)。后来在CLAUDE.md中补充了“使用MyBatis-Plus 3.5.x,禁止使用JPA”的规则,之后生成的代码就统一了。

审计日志的记录方式

如前所述,AI最初使用AOP切面自动记录审计日志。看起来省事,但实际效果是记录的信息过于粗糙——只能获取方法名,无法拿到变更前后的具体值。后来改为在Controller中手动调用auditLogService.logAudit(),虽然多写几行代码,但每条审计日志的detail字段都能清晰描述具体操作内容。

异常处理统一化

AI生成的Controller中,有些地方抛出RuntimeException,有些地方返回null。后来在CLAUDE.md中增加了“使用BusinessException抛出业务异常”的规则,同时编写了GlobalExceptionHandler进行统一处理:

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(BusinessException.class)
    public ApiResponse handleBusinessException(BusinessException e) {
        return ApiResponse.error(e.getCode(), e.getMessage());
    }
    @ExceptionHandler(PermissionDeniedException.class)
    public ApiResponse handlePermissionDenied(PermissionDeniedException e) {
        return ApiResponse.error(403, e.getMessage());
    }
}

需求越精细,返工越少

回顾这三个问题,它们都不是技术难题,而是“初始需求描述不够细致”所导致的。因此现在养成了一个习惯:让AI编写代码之前,先花10分钟把需求细化到“不需要追问”的程度。不是写冗长的文档,而是在对话中把关键点表达清楚:

/implement 按照任务清单实现权限模块,注意以下要点:
1. 使用 MyBatis-Plus,禁止使用 JPA
2. 权限校验采用 @RequirePermission 注解 + AOP 拦截
3. 统一使用 BusinessException 抛出业务异常
4. 审计日志在 Controller 中手动调用 logAudit 记录
5. 所有返回结果使用 ApiResponse 包装

这几条看似都是常识(“使用MyBatis-Plus”、“抛出BusinessException”谁都知道),但你不说AI就不会主动执行。AI并非不了解MyBatis-Plus,而是不知道你的项目已经确定了技术栈,需要它主动遵守。需求描述得越精细,返工次数就越少,上下文token的浪费也越少。这个道理与带新人其实一致——交代任务时不说清楚,新人做出来的结果肯定不是你要的,随后反复沟通,双方都疲惫。

完成后的几点体会

这次全流程走下来,AI真正发挥价值的环节包括:

表现优异的方面:

  • 数据模型设计——标准RBAC模型,AI生成的表结构和关联关系没有出现错误
  • 实体类和Mapper——MyBatis-Plus代码是AI最擅长的领域,生成质量与手写相当
  • AOP拦截器——标准模式,训练数据充足,一次编写正确
  • 全局异常处理——RestControllerAdvice模板代码,AI生成得非常完整

需要人工介入的部分:

  • 方案选择(RBAC vs 策略 vs SpEL)——这属于架构判断,AI只能列出选项
  • 技术栈对齐——AI默认混用JPA和MyBatis,需要人工提前明确
  • 审计日志的记录方式——AOP自动记录还是手动调用,需要根据业务场景判断
  • 异常类型的统一化——AI会混用RuntimeException和自定义异常,需要人工规范

结论是:AI能够把标准工作完成得又快又好,但非标准的坑需要你自己去填补。踩过坑之后把经验写回规则文件,下次AI就不会再犯同样的错误。这个闭环一旦运转顺畅,开发效率确实比以往提升了不少。

本文对应的代码仓库已在Gitee开源:gitee.com/tangyuewei/…,包含RBAC权限系统的完整实现、CLAUDE.md规则文件以及开发过程中的提示词记录,可以直接拉取运行。

来源:https://juejin.cn/post/7653410900831895579
下一篇: AI in Harness 第4篇

游乐网为非赢利性网站,所展示的游戏/软件/文章内容均来自于互联网或第三方用户上传分享,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系youleyoucom@outlook.com。

同类文章
更多
跨境物流AI Agent感知决策全链路自动化技术拆解

跨境物流AI Agent感知决策全链路自动化技术拆解

2026年,跨境物流领域正迎来一场根本性变革——从“被动记录”全面迈向“主动执行”,AI智能体正在重塑整个行业格局。 你可能已经深有体会:每天一到岗,光是后台处理货件创建、物流追踪等重复操作,就要耗费数小时之久。行业调研数据显示,超过60%的运营人员每天至少花费2小时在这些机械性劳动上,而手动操作引

时间:2026-07-11 16:50
天学会AI应用开发第十二课:从PDF、Word和网页构建RAG

天学会AI应用开发第十二课:从PDF、Word和网页构建RAG

上一篇文章介绍了如何从TXT文件中读取文本内容,但在日常办公场景中,纯文本文件的使用频率并不高。更常见的需求是处理PDF、Word等文档格式,同时还需要从网页中提取知识信息。 因此,本篇文章将重点讲解如何从PDF、Word以及网页中提取内容,并将其应用于RAG(检索增强生成)系统。 一、从PDF文件

时间:2026-07-11 16:50
Hy3+WorkBuddy组合国产顶级Agent附完整提示词

Hy3+WorkBuddy组合国产顶级Agent附完整提示词

五个 Case 跑完,总结一下整体体验。工具使用能力:能不能自己开网页、找信息、标出处。规划能力:能不能把多约束需求拆成可执行步骤。长程执行能力:跨多步任务时会不会丢状态。复杂推理能力:能不能先推导、再写代码、再执行验证。WorkBuddy+Hy3 的表现完全符合预期。趁着 WorkBuddy 里的

时间:2026-07-11 16:50
AI Agent是什么?一文理解大语言模型、记忆、技能、工具、MCP、工作流与上下文

AI Agent是什么?一文理解大语言模型、记忆、技能、工具、MCP、工作流与上下文

智能体并非单一模型,而是由大语言模型、记忆、工具、工作流等模块协同构成的自主系统。它通过理解目标、检索记忆、调用工具、构建上下文、推理决策,并基于反馈闭环持续迭代,最终自主完成复杂任务。

时间:2026-07-11 16:50
DeepSeek决定自研芯片打造人工智能全新算力芯脏

DeepSeek决定自研芯片打造人工智能全新算力芯脏

被“逼”出来的第三条路。 一直以模型技术见长的DeepSeek,这次在算力供应链上迈出了让所有人侧目的一步。 2026年7月7日,路透社援引三位知情人士消息,DeepSeek正在悄然开发自有AI芯片。值得玩味的是,这颗芯片的定位非常精准——专攻推理,不涉足训练。消息人士称,项目大约启动于一年前,目前

时间:2026-07-11 16:28
热门专题
更多
刀塔传奇破解版无限钻石下载大全 刀塔传奇破解版无限钻石下载大全
洛克王国正式正版手游下载安装大全 洛克王国正式正版手游下载安装大全
思美人手游下载专区 思美人手游下载专区
好玩的阿拉德之怒游戏下载合集 好玩的阿拉德之怒游戏下载合集
不思议迷宫手游下载合集 不思议迷宫手游下载合集
百宝袋汉化组游戏最新合集 百宝袋汉化组游戏最新合集
jsk游戏合集30款游戏大全 jsk游戏合集30款游戏大全
宾果消消消原版下载大全 宾果消消消原版下载大全
  • 热门数据榜