基于RBAC模型的权限系统设计与实现:Spring Boot与Vue 3全栈开发实践

📅 发布时间:2026/8/27 4:59:04
基于RBAC模型的权限系统设计与实现:Spring Boot与Vue 3全栈开发实践 1. 项目缘起与核心思路最近在做一个内部管理平台用户角色和权限这块儿的需求越来越复杂。一开始就是简单的“管理员”和“普通用户”二分法后来业务部门提需求什么“区域经理只能看自己区域的报表”、“财务只能审核不能创建订单”、“客服只能处理工单不能看成本”……权限颗粒度越来越细手动在代码里写if-else判断角色已经难以为继每次加新功能都要改一堆判断逻辑还容易出错。这时候一个结构化的权限管理系统就成了刚需。业内成熟的方案就是 RBACRole-Based Access Control基于角色的访问控制模型。它的核心思想是把“用户”和“权限”解耦通过“角色”这个中间层来关联。权限分配给角色角色再分配给用户。这样一来增加一个新功能我只需要定义好这个功能需要的权限然后把这个权限赋给相应的角色即可所有拥有该角色的用户就自动获得了权限管理起来清晰又高效。正好最近在深入研究 AI 辅助编程我就想能不能把这次权限系统的开发过程作为一个完整的实验让 AI 从零开始参与甚至主导我的角色是“产品经理”和“架构师”负责提出需求、审核设计、检查代码而 AI 则作为“高级开发工程师”负责完成从技术选型、数据库设计、接口实现到前端页面的大部分编码工作。我想验证一下在当前的技术条件下一个有一定经验的开发者借助 AI能否高效、可靠地完成一个中等复杂度的全栈项目。这个项目将采用经典的前后端分离架构后端用 Spring Boot 提供 RESTful API前端用 Vue 3 构建用户界面。权限模型采用 RBAC 的核心思想并扩展了用户-角色-权限-菜单的关联。下面我就把这次“人机协作”开发用户权限系统的全过程包括技术决策、踩过的坑、以及 AI 在实际编码中的表现毫无保留地记录下来。2. 系统架构设计与技术选型考量在动手写代码之前清晰的架构设计是成功的基石。我需要和 AI 搭档一起把系统的骨架搭好。2.1 为什么选择 RBAC 模型首先得统一思想为什么是 RBAC而不是更简单的 ACL访问控制列表或者更复杂的 ABAC基于属性的访问控制ACL 直接将用户与资源权限挂钩比如“用户A可以读文件B”。这在用户和资源数量少的时候简单直接但当用户成千上万资源也海量时维护成本是指数级上升。想象一下公司来了个新员工我需要为他手动配置上百个系统的访问权限这几乎是不可能的。ABAC 则更加动态和精细它通过用户属性部门、职位、环境属性时间、IP和资源属性来判断权限。比如“在工作时间来自公司内网的财务部员工可以访问报销系统”。这非常强大但也非常复杂需要一套策略引擎对于我当前这个内部管理平台来说有点杀鸡用牛刀引入的学习和维护成本过高。RBAC 则在灵活性和复杂性之间取得了很好的平衡。它通过“角色”这一层抽象完美匹配了企业的组织结构。现实中权限本来就是按岗位角色来划分的。新增一个员工我只需要给他分配“财务专员”这个角色他就自动拥有了该角色的所有权限。调整权限时也只需要修改“财务专员”这个角色的权限集所有财务专员的权限都会同步更新。这种“用户-角色-权限”的三层模型概念清晰管理方便是绝大多数后台系统的首选。在我们的设计中还会对经典 RBAC 做一点扩展引入“菜单”或“资源”的概念。权限不仅控制 API 接口的访问也控制前端侧边栏菜单的显示与隐藏实现全方位的权限管控。2.2 后端技术栈Spring Boot 为何胜出后端需要快速构建稳健的 REST API处理业务逻辑和数据库交互。Spring Boot 几乎是 Java 生态中的不二之选原因有几个第一是“约定大于配置”的理念。它提供了海量的 Starter 依赖像spring-boot-starter-webWeb、spring-boot-starter-data-jpa数据库等我只需要在pom.xml里声明依赖绝大部分配置如服务器端口、数据库连接池、JSON序列化Spring Boot 都给出了合理的默认值让我能专注于业务代码。这极大地提升了开发效率也降低了 AI 在配置环节出错的概率。第二是强大的生态和社区支持。权限控制方面Spring Security 是业界标杆。它与 Spring Boot 无缝集成提供了从认证Authentication到授权Authorization的一整套安全解决方案。我们可以利用它的过滤器链、PreAuthorize注解等能力优雅地实现接口级别的权限拦截。第三是成熟稳定。Spring Boot 经历了大量企业级项目的检验其稳定性、性能和对微服务的支持都非常出色。这对于一个可能长期演进、用户逐渐增多的内部系统来说是重要的技术保障。在给 AI 的指令中我明确要求使用 Spring Boot 3.x 版本当时最新稳定版是 3.1.x并搭配 Java 17。新版本在性能、模块化尤其是对 GraalVM 原生镜像的支持和 API 设计上都有改进。2.3 前端技术栈Vue 3 的组合式 API 优势前端需要构建一个动态、交互良好的管理界面。Vue.js 以其渐进式、易上手的特点在中小型项目中非常受欢迎。我选择 Vue 3 而不是 Vue 2主要看中了其 Composition API组合式 API。在 Vue 2 的 Options API 中代码是按照data、methods、computed等选项来组织的。当一个组件的逻辑复杂时这些逻辑会被拆分到不同的选项中导致阅读和维护时需要不断上下滚动关联性强的代码反而被割裂了。Vue 3 的 Composition API 允许我们将与同一个功能相关的ref响应式数据、computed计算属性、function方法封装在一个独立的函数比如useUserPermission中。这样组件的逻辑可以按功能点进行聚合而不是按选项类型分离。对于权限系统这种需要多处复用权限判断逻辑的场景Composition API 能让我们更容易地抽取和复用逻辑代码结构更清晰也更利于 AI 理解和生成模块化的代码。UI 组件库方面我选择了 Element Plus。它是基于 Vue 3 的组件丰富、设计成熟文档齐全能快速搭建出专业的管理后台界面。像表格、表单、弹窗、树形控件这些权限管理页面高频使用的组件它都提供了很好的支持。2.4 数据库设计核心表结构解析数据库是系统的基石一个糟糕的设计会让后续开发举步维艰。我和 AI 花了相当长的时间来讨论和确定表结构。最终的核心表如下我要求 AI 不仅要给出 SQL还要解释每个字段和关联关系的设计意图用户表 (sys_user)存储系统用户的基本信息。id主键。username登录用户名唯一。password加密后的密码必须用 BCrypt 等强哈希算法。nickname显示名称。status账户状态0-禁用1-启用。这是软删除或临时封禁的关键字段。create_time,update_time记录创建和更新时间。角色表 (sys_role)定义系统中的角色。id主键。role_key角色唯一标识符如admin,finance用于程序中判断。role_name角色显示名称如“系统管理员”、“财务专员”。description角色描述。status角色状态0-停用1-启用。停用的角色不能分配给新用户。权限表 (sys_permission)定义最小的权限单元。id主键。perm_key权限唯一标识符通常与后端接口或前端按钮绑定如user:add,order:query。遵循资源:操作的命名约定是个好习惯。perm_name权限显示名称如“新增用户”、“查询订单”。menu_id关联菜单表。这是关键设计将权限与前端的一个菜单项或页面组件绑定。一个菜单可以对应多个权限如页面的增删改查按钮但一个权限通常只属于一个菜单。菜单表 (sys_menu)定义前端路由和侧边栏菜单。id主键。parent_id父菜单ID用于构建树形结构。menu_name菜单名称。path前端路由路径如/user。componentVue组件路径如User/index.vue。icon菜单图标。order_num排序号。visible是否在侧边栏显示0-隐藏1-显示。有些页面如404不需要显示在菜单中。用户-角色关联表 (sys_user_role)多对多关系记录用户拥有哪些角色。user_idrole_id角色-权限关联表 (sys_role_permission)多对多关系记录角色拥有哪些权限。role_idpermission_id设计心得将“菜单”从“权限”中独立出来是经过深思熟虑的。菜单更偏向于前端导航和路由而权限是控制能否访问某个功能点。一个菜单页面如“用户管理”可能对应“查询用户”、“新增用户”、“删除用户”等多个权限。这样设计前端可以根据用户拥有的权限动态决定这个菜单页面内的按钮是显示还是禁用实现了非常精细的界面级控制。3. 后端核心实现Spring Boot Spring Security 实战有了清晰的设计图就可以开始让 AI “施工”了。后端是整个系统的引擎我要求 AI 按照模块化的思路来构建。3.1 项目初始化与依赖配置首先我让 AI 使用 Spring Initializr 的模板生成一个基础的 Spring Boot 3.x 项目。核心依赖包括spring-boot-starter-web: 提供 Web MVC 支持。spring-boot-starter-data-jpa: 用于数据库操作这里我们选用 JPA 的规范具体实现可以用 Hibernate。spring-boot-starter-security: 核心安全框架。mysql-connector-j或postgresql: 数据库驱动根据你的选择来定。lombok: 减少 getter/setter 等样板代码。jjwt: 用于生成和解析 JWT (JSON Web Token)实现无状态的认证。AI 生成了pom.xml后我检查了版本号确保没有冲突并特别提醒它要在application.yml中正确配置数据库连接信息和 JWT 的密钥、过期时间。3.2 数据层与实体类建模接下来是根据数据库设计创建 JPA 实体类。这是 AI 表现非常出色的地方。我只需要描述表结构它就能生成符合 JPA 规范的实体类包括正确的注解Entity,Table,Id,GeneratedValue和关联关系ManyToMany,JoinTable。例如在User实体中它与Role是多对多关系。AI 生成的代码如下Entity Table(name sys_user) Data // Lombok 注解自动生成 getter, setter 等 public class User { Id GeneratedValue(strategy GenerationType.IDENTITY) private Long id; Column(unique true, nullable false) private String username; Column(nullable false) private String password; private String nickname; private Integer status; ManyToMany(fetch FetchType.LAZY) // 延迟加载避免一次查询过多数据 JoinTable(name sys_user_role, joinColumns JoinColumn(name user_id), inverseJoinColumns JoinColumn(name role_id)) private SetRole roles new HashSet(); // 创建时间、更新时间等字段可以用 CreationTimestamp 和 UpdateTimestamp }注意事项这里有一个关键点就是FetchType.LAZY延迟加载。在查询用户时默认不应该连带查出他所有的角色和权限这会造成“N1”查询问题严重拖慢性能。我们应该在需要的时候比如登录后构建用户详情再通过专门的 Service 方法或EntityGraph注解来主动加载这些关联数据。我在审核代码时向 AI 强调了这一点它后续在编写查询服务时也注意到了。3.3 Spring Security 深度定制从认证到授权这是权限系统的核心也是最复杂的部分。Spring Security 的默认配置不符合我们的需求需要深度定制。我向 AI 描述了整个流程登录认证用户提交用户名密码系统验证成功后生成一个 JWT Token 返回给前端。请求鉴权前端后续请求在 Header 中携带此 Token。后端需要有一个过滤器来解析 Token验证其有效性并从中提取用户信息将其放入 SecurityContext安全上下文中这样后续的代码就能知道当前请求是谁发起的。权限校验在具体的 API 接口上使用PreAuthorize注解根据用户拥有的权限来判断是否允许访问。AI 需要实现以下几个关键组件JwtAuthenticationFilter一个继承自OncePerRequestFilter的过滤器。它从请求头Authorization中提取 JWT Token调用JwtUtil进行解析和验证如果成功则根据用户ID从数据库加载完整的用户信息包括角色和权限并构建一个Authentication对象设置到SecurityContextHolder中。JwtUtil一个工具类负责生成 JWT、解析 JWT、验证 JWT 是否过期等。UserDetailsServiceImpl实现 Spring Security 的UserDetailsService接口。它的loadUserByUsername方法在登录认证时被调用用于根据用户名从数据库加载用户。这里返回的UserDetails对象需要包含用户的权限信息格式通常是ROLE_ADMIN或user:add这样的字符串。SecurityConfiguration核心配置类使用EnableWebSecurity和Configuration注解。在这里我们需要禁用默认的 Session 管理因为我们用无状态的 JWT。配置密码编码器必须使用BCryptPasswordEncoder。定义哪些路径是公开的如登录接口、Swagger UI哪些需要认证。将我们自定义的JwtAuthenticationFilter添加到过滤器链中在标准的UsernamePasswordAuthenticationFilter之前。启用方法级安全注解EnableMethodSecurity(prePostEnabled true)这样PreAuthorize才能生效。AI 在生成这部分代码时遇到了一个典型问题它最初在UserDetailsServiceImpl中返回的权限字符串列表是ListString但在配置PreAuthorize时注解里需要的是hasAuthority(user:add)这样的表达式。它一开始返回的是角色名如ROLE_ADMIN这会导致基于具体权限的校验失败。我指出问题后它修正为从数据库查询用户拥有的所有Permission的perm_key并将其作为权限列表返回。3.4 业务逻辑层权限的增删改查这部分相对标准就是围绕User,Role,Permission,Menu这几个实体实现 CRUD 服务。但有一些业务逻辑需要特别注意用户管理创建用户时必须对密码进行 BCrypt 加密。删除用户通常是逻辑删除更新status字段为禁用。为用户分配角色时需要更新sys_user_role关联表。角色管理为角色分配权限是核心操作。这涉及到更新sys_role_permission表。前端通常会以树形结构展示所有权限供管理员勾选。菜单管理菜单是树形结构需要提供一个接口能递归查询出完整的菜单树。并且这个接口返回的菜单应该是当前登录用户有权访问的菜单。这意味着后端需要根据用户的角色和权限过滤掉那些用户没有权限的菜单项。AI 在这里实现了一个递归查询并过滤的方法是后端的一个小亮点。权限校验接口我们还需要一个接口让前端查询当前用户对所有权限点的拥有情况。前端可以将这个结果缓存起来用于控制按钮的显示/隐藏状态。这个接口的实现本质上就是把UserDetails中的权限列表返回给前端。3.5 API 接口设计与PreAuthorize注解的应用RESTful 接口设计遵循标准规范。重点在于如何使用PreAuthorize进行权限控制。RestController RequestMapping(/api/users) public class UserController { Autowired private UserService userService; GetMapping PreAuthorize(hasAuthority(user:query)) // 必须拥有‘查询用户’的权限 public ResponseEntityListUserVO listUsers() { // ... 业务逻辑 } PostMapping PreAuthorize(hasAuthority(user:add)) // 必须拥有‘新增用户’的权限 public ResponseEntity? createUser(RequestBody Valid CreateUserRequest request) { // ... 业务逻辑 } DeleteMapping(/{id}) PreAuthorize(hasAuthority(user:delete)) // 必须拥有‘删除用户’的权限 public ResponseEntity? deleteUser(PathVariable Long id) { // ... 业务逻辑 } }实操心得PreAuthorize表达式非常灵活。除了hasAuthority还可以用hasRole会自动前缀ROLE_、hasAnyAuthority、hasAnyRole甚至可以使用 SpEL 表达式进行更复杂的判断比如检查操作的对象是否属于当前用户 (PreAuthorize(#id authentication.principal.id))。AI 在生成控制器代码时能够根据我提供的权限键perm_key列表自动为每个接口添加合适的注解这大大减少了手动标注的工作量。4. 前端核心实现Vue 3 Element Plus 动态权限渲染前端的目标是构建一个能够根据用户权限动态变化的界面。这包括动态路由、动态侧边栏菜单、以及页面内按钮级别的权限控制。4.1 项目初始化与路由设计首先使用 Vite 创建 Vue 3 TypeScript 项目并安装 Element Plus、Vue Router、Axios 等依赖。路由设计分为两部分静态路由和动态路由。静态路由包括登录页、404页面等所有用户都能访问的页面。动态路由需要权限才能访问的业务页面如用户管理、角色管理等。这些路由的定义不直接写死在router/index.ts里而是等待用户登录后从后端获取的菜单列表来动态添加。AI 需要编写一个路由守卫router.beforeEach在用户跳转到任何页面之前进行拦截。守卫的逻辑是如果目标页面是白名单如登录页直接放行。检查本地如 localStorage是否有 Token。如果没有 Token跳转到登录页。如果有 Token则检查是否已经加载过用户信息和动态路由。如果没加载过则调用后端接口获取用户信息和菜单列表然后根据菜单列表动态生成路由对象并通过router.addRoute()方法添加到路由实例中。最后再跳转到目标页面。4.2 动态菜单生成从数据到侧边栏这是前端权限系统的视觉核心。后端返回的菜单列表是一个树形结构的 JSON 数据。AI 需要编写一个递归组件SidebarMenu.vue来渲染这个菜单树。!-- 简化示例 -- template el-menu :routertrue template v-foritem in menuList :keyitem.id el-sub-menu v-ifitem.children item.children.length :indexitem.path template #title el-iconcomponent :isitem.icon //el-icon span{{ item.menu_name }}/span /template !-- 递归调用自身组件 -- sidebar-menu :menu-listitem.children / /el-sub-menu el-menu-item v-else :indexitem.path el-iconcomponent :isitem.icon //el-icon span{{ item.menu_name }}/span /el-menu-item /template /el-menu /template script setup langts defineProps{ menuList: MenuItem[] // MenuItem 是定义好的类型接口 }(); /script踩坑记录在动态添加路由时AI 最初犯了一个错误它直接把后端返回的菜单path如/system/user当作路由的path把component字段如system/user/index直接用于component属性。但在 Vue Router 中component需要的是一个导入的组件引用而不是字符串。我们需要实现一个函数将字符串路径动态转换为组件引用这通常通过() import(/views/${menu.component}.vue)来实现。我指出这个问题后AI 修正了代码实现了一个路由映射加载器。4.3 按钮级权限控制自定义指令 v-permission控制菜单显示只是第一步更精细的控制是页面内的按钮。我们不可能在每个按钮上都写v-if来判断权限。最佳实践是创建一个自定义指令v-permission。// directives/permission.ts import type { App } from vue; import { useUserStore } from /stores/user; // 假设使用 Pinia 存储用户权限 export function setupPermissionDirective(app: App) { app.directive(permission, { mounted(el, binding) { const { value } binding; // value 是指令的值例如 user:add const userStore useUserStore(); const permissions userStore.permissions; // 从状态管理获取权限列表 if (value Array.isArray(permissions)) { const hasPermission permissions.includes(value); if (!hasPermission) { el.parentNode?.removeChild(el); // 没有权限直接移除DOM元素 } } else { throw new Error(需要权限标识如 v-permissionuser:add); } }, }); }然后在main.ts中注册这个指令。在组件中就可以优雅地使用了template el-button v-permissionuser:add typeprimary clickhandleAdd新增用户/el-button el-button v-permissionuser:delete typedanger clickhandleDelete删除用户/el-button /template4.4 状态管理与 API 集成使用 Pinia 来管理全局状态特别是用户信息、权限列表和菜单列表。登录成功后将 Token 存入 localStorage 或 cookie并将用户信息和权限列表存入 Pinia Store。所有对后端的 API 调用都封装在统一的request.ts文件中使用 Axios 实例。在这里需要设置请求拦截器自动为每个请求的 Header 加上Authorization: Bearer ${token}。同时设置响应拦截器统一处理错误如 Token 过期返回 401则跳转到登录页。AI 在编写这部分时对 Axios 拦截器和 Pinia 的配合使用得很熟练生成的代码结构清晰。5. 联调、测试与常见问题排查前后端代码都生成完毕后就进入了激动人心的联调阶段。这个过程也是问题暴露最集中的阶段。5.1 跨域问题 (CORS)这是第一个拦路虎。前端运行在localhost:5173后端在localhost:8080浏览器会因为同源策略而阻止请求。AI 在后端SecurityConfiguration中正确配置了 CORSBean public CorsFilter corsFilter() { UrlBasedCorsConfigurationSource source new UrlBasedCorsConfigurationSource(); CorsConfiguration config new CorsConfiguration(); config.setAllowCredentials(true); // 允许携带凭证如cookies config.addAllowedOriginPattern(*); // 在生产环境中应替换为具体的前端地址 config.addAllowedHeader(*); config.addAllowedMethod(*); source.registerCorsConfiguration(/**, config); return new CorsFilter(source); }注意addAllowedOriginPattern(*)在开发环境方便但上线后必须替换为确切的前端域名如https://admin.xxx.com否则会带来安全风险。5.2 JWT Token 失效与刷新我们设置的 Token 过期时间可能是 2 小时。用户如果连续操作2小时后会突然“被登出”体验很差。一种常见的优化方案是使用“双 Token”机制Access Token短期如2小时和 Refresh Token长期如7天。当 Access Token 过期后前端用 Refresh Token 去请求一个新的 Access Token用户无感知。AI 最初实现的简单单 Token 方案。我提出了这个体验问题它随后补充了 Refresh Token 的逻辑登录时同时返回两个 Token前端在请求拦截器中判断如果接口返回 401Token过期则自动调用 Refresh 接口获取新 Token然后重试原请求。5.3 权限数据同步与缓存用户的权限数据在登录时加载并存入前端 Store。但如果管理员在后台实时修改了用户的角色或权限已登录的用户在前端是无法立即感知的必须退出重新登录才行。对于要求实时性极高的系统可以考虑使用 WebSocket 推送权限变更通知。但对于大多数内部管理系统这个延迟是可以接受的。我们采取了一种折中方案在关键权限操作如进入某个管理页面时可以主动调用一次“获取用户信息”的接口以同步最新的权限但这会增加请求次数。5.4 按钮权限与页面路由的边界情况我们实现了v-permission指令来控制按钮。但有一种情况用户通过手动输入 URL/system/user直接访问某个他没有权限的页面。虽然菜单上不显示这个入口但路由是存在的。这时前端路由守卫应该在加载页面组件前检查用户是否有该页面所需的权限可以约定一个权限标识如page:user或者检查该页面路由对应的菜单项是否在用户菜单列表中。如果没有则跳转到 403 无权限页面。AI 在最初的路由守卫中只检查了 Token我补充了这个权限检查的逻辑。5.5 数据库查询性能优化随着用户、角色、权限数据的增多在登录时一次性查询用户的所有角色和权限包括关联的菜单可能会产生复杂的联表查询影响性能。我们采用了以下策略缓存将用户的权限列表字符串格式在登录后缓存在 Redis 中Key 为用户ID设置合理的过期时间。下次需要权限校验时直接从缓存读取避免频繁查询数据库。分批加载登录时只加载用户基本信息和一个最小的权限标识列表用于生成JWT和前端基础校验。完整的菜单树和详细的权限信息可以在用户进入主界面后再通过单独的接口异步加载。数据库索引确保sys_user_role.user_id,sys_role_permission.role_id等关联字段上建立了索引。6. AI 协作开发的全过程反思与经验总结回顾整个项目AI我使用的是基于大型语言模型的编程助手扮演了一个不知疲倦、知识渊博、但有时缺乏“常识”和“上下文”的初级高级工程师。它的优势非常明显效率爆炸像实体类、基础的 CRUD Service、Controller、甚至前端的表单页面和表格组件我只需要给出清晰的描述它就能在几秒钟内生成结构正确、语法无误的代码。这节省了至少 60% 的纯编码时间。知识广度它对 Spring Security、Vue Router、Pinia、Element Plus 等框架的 API 非常熟悉能快速给出符合最佳实践的代码片段我不用再去翻官方文档查某个方法的具体用法。减少琐碎错误它生成的代码在语法和基础逻辑上错误很少避免了因拼写、括号不匹配等低级错误导致的调试时间。但它的局限性也同样突出需要“人类架构师”严格把关缺乏整体架构观AI 擅长完成具体的、局部的任务。但整个系统的模块划分、数据流设计、前后端交互协议、异常处理规范等必须由我来主导。它不会主动说“这里用缓存更好”或者“这个接口设计成 RESTful 风格更合适”。对“业务逻辑”理解肤浅它理解“为用户分配角色”这个操作是更新关联表但它不理解为什么要在分配前检查角色状态是否启用也不理解为什么删除用户最好是逻辑删除而非物理删除。这些包含业务规则和产品思维的逻辑必须由我明确告知。代码“正确”但不“优美”AI 生成的代码有时冗余或者没有使用更优雅的设计模式。例如它最初生成的权限校验工具类是一个静态方法类而我后来引导它改成了更易于测试和扩展的基于 Spring Bean 的服务。调试能力为零当联调出现问题时AI 只能根据错误信息猜测可能的原因。真正的调试——查看日志、分析网络请求、使用断点——必须由我来完成。然后我再把观察到的现象和错误信息反馈给它它才能给出修正建议。给想尝试 AI 辅助开发的同行的建议你必须是合格的架构师和代码审查员AI 是你的“执行者”你必须是“决策者”和“质检员”。你的技术功底越扎实就越能发挥 AI 的威力也越能及时发现它的错误。任务拆解要极其细致不要给 AI 一个模糊的指令如“实现登录功能”。而要拆解成“基于 Spring Security 和 JWT实现一个登录接口/api/auth/login接收username和password验证成功后返回一个包含access_token和refresh_token的 JSON 对象Token 有效期为2小时和7天。” 越具体产出越精准。循序渐进步步为营不要指望 AI 一次生成整个模块。应该从数据库实体开始然后到 Repository再到 Service最后到 Controller。每完成一步就运行测试一下确保基础牢固。善用对话持续优化把 AI 当作一个结对编程的伙伴。当它生成的代码不符合预期时不要直接重写而是告诉它哪里不对为什么不对你希望它变成什么样。这个过程本身也是对你思路的梳理。这次“让 AI 从零做一个用户权限系统”的实验是成功的。它证明了在当前阶段AI 已经能成为开发者的强大助力显著提升开发效率。但它远未到能替代开发者的程度。核心的架构设计、复杂的业务逻辑、深度的调试优化以及最重要的——理解需求并将其转化为技术方案的能力仍然牢牢掌握在人类开发者手中。未来善于利用 AI 的开发者和不会利用 AI 的开发者其生产力差距可能会越来越大。