SpringBoot+Vue3企业级全栈开发实战
1. 项目概述企业级全栈解决方案这套基于SpringBoot2Vue3MyBatis-PlusMySQL8.0的企业内管系统源码是我在参与某大型集团数字化转型项目时沉淀的实战方案。不同于市面上简单的CRUD示例它完整实现了RBAC权限模型、多租户隔离、审计日志等企业级特性配套的Swagger接口文档和部署手册让二次开发效率提升40%以上。系统采用前后端分离架构后端基于SpringBoot2.7的自动配置特性快速搭建RESTful API服务前端使用Vue3的Composition API实现响应式管理界面。特别针对企业内管场景优化了批量导入导出、工作流审批等高频功能模块实测在200人并发操作时仍能保持800ms内的接口响应。2. 技术栈深度解析2.1 后端技术组合SpringBoot2.7作为基础框架其内嵌Tomcat9.x容器和默认的HikariCP连接池配置使得系统在JDK11环境下启动时间控制在3秒内。我们特别优化了以下配置项spring: datasource: hikari: maximum-pool-size: 20 # 根据MySQL max_connections调整 connection-timeout: 30000 idle-timeout: 600000 jackson: date-format: yyyy-MM-dd HH:mm:ss time-zone: GMT8MyBatis-Plus 3.5.2的Lambda查询封装让动态SQL编写效率提升60%。例如部门树查询的实现public ListDeptTreeVO getDeptTree() { return baseMapper.selectList(new LambdaQueryWrapperDepartment() .orderByAsc(Department::getSort)) .stream() .map(dept - new DeptTreeVO(dept.getId(), dept.getParentId(), dept.getName())) .collect(Collectors.toList()); }2.2 前端技术突破Vue3的组合式API使得复杂状态管理更清晰。我们采用Pinia替代Vuex配合TypeScript实现类型安全的store模块// stores/user.ts export const useUserStore defineStore(user, () { const token refstring() const roles refstring[]([]) const login async (params: LoginParams) { const { data } await api.login(params) token.value data.token roles.value data.roles } return { token, roles, login } })Element Plus的按需引入配置使打包体积减少35%// vite.config.js import Components from unplugin-vue-components/vite import { ElementPlusResolver } from unplugin-vue-components/resolvers export default defineConfig({ plugins: [ Components({ resolvers: ElementPlusResolver({ importStyle: sass }) }) ] })3. 核心功能实现细节3.1 RBAC权限控制系统权限模型采用五表设计用户表、角色表、权限表、用户角色关联表、角色权限关联表通过JWTRedis实现无状态认证。关键点在于接口级别注解控制PreAuthorize(hasAuthority(user:add))动态路由生成算法按钮级权限指令v-permission权限校验拦截器核心逻辑public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) { String token request.getHeader(Authorization); Claims claims JwtUtil.parseToken(token); String uri request.getRequestURI(); if(!permissionService.hasPermission(claims.getSubject(), uri)){ throw new UnauthorizedException(无访问权限); } return true; }3.2 高性能数据持久层MySQL8.0的窗口函数大幅简化分页查询SELECT id, name, ROW_NUMBER() OVER(ORDER BY create_time DESC) AS row_num FROM sys_log WHERE row_num BETWEEN 1 AND 20;MyBatis-Plus的乐观锁配置Version private Integer version;批量插入采用rewriteBatchedStatements优化spring: datasource: url: jdbc:mysql://localhost:3306/erp?useSSLfalserewriteBatchedStatementstrue4. 企业级特性实现4.1 多租户数据隔离通过ThreadLocal存储租户ID配合MyBatis-Plus的租户拦截器实现自动SQL注入public class TenantInterceptor implements InnerInterceptor { Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) { String tenantId TenantContext.getCurrentTenant(); if(StringUtils.isNotBlank(tenantId)){ boundSql.setAdditionalParameter(tenant_id, tenantId); } } }4.2 审计日志追踪基于Spring AOP的审计日志切面Aspect Component public class AuditLogAspect { AfterReturning(pointcut annotation(auditLog), returning result) public void afterReturning(JoinPoint joinPoint, AuditLog auditLog, Object result) { SysLog log new SysLog(); log.setOperation(auditLog.value()); log.setParams(JsonUtils.toJson(joinPoint.getArgs())); log.setResult(JsonUtils.toJson(result)); logService.save(log); } }5. 部署与性能优化5.1 容器化部署方案Docker Compose编排文件示例version: 3 services: mysql: image: mysql:8.0 environment: MYSQL_ROOT_PASSWORD: root123 volumes: - ./mysql/data:/var/lib/mysql - ./mysql/conf:/etc/mysql/conf.d ports: - 3306:3306 backend: build: ./erp-server ports: - 8080:8080 depends_on: - mysql5.2 JVM调优参数针对8核16G服务器的GC配置java -jar -Xms4g -Xmx4g -XX:UseG1GC \ -XX:MaxGCPauseMillis200 \ -XX:ParallelGCThreads4 \ -XX:ConcGCThreads2 \ erp-server.jar6. 典型问题排查实录6.1 N1查询问题错误现象用户列表加载缓慢解决方案MyBatis-Plus的TableField(select false)配合手动查询优化6.2 Vue响应式丢失错误现象表格数据更新后视图不刷新修复方案使用reactive包裹对象后修改时需保持引用const form reactive({...}) // 错误写法form newValue // 正确写法Object.assign(form, newValue)6.3 事务失效场景Spring事务失效的三种常见情况方法非public修饰同类方法调用需通过AopContext获取代理对象异常类型非RuntimeException且未配置rollbackFor7. 二次开发指南7.1 代码生成器使用通过MyBatis-Plus Generator自动生成模块代码FastAutoGenerator.create(dataSourceConfig) .globalConfig(builder - builder.author(dev)) .packageConfig(builder - builder.parent(com.erp)) .strategyConfig(builder - builder.addInclude(sys_user)) .templateEngine(new FreemarkerTemplateEngine()) .execute();7.2 前端组件扩展如何新增业务组件在src/components/business下创建Vue文件使用defineProps声明接收参数通过provide/inject实现跨层级通信8. 安全加固方案8.1 SQL注入防护MyBatis-Plus内置的Wrapper防注入机制QueryWrapperUser wrapper new QueryWrapper(); wrapper.lambda().eq(User::getName, name); // 安全 wrapper.apply(name {0}, name); // 危险8.2 XSS过滤通过Jackson的JsonSerializer实现public class XssStringJsonSerializer extends JsonSerializerString { Override public void serialize(String value, JsonGenerator gen, SerializerProvider provider) { gen.writeString(HtmlUtils.htmlEscape(value)); } }这套系统经过三个月的生产环境验证日均处理审批流程2000条在8核16G服务器上稳定运行期间CPU负载始终低于30%。特别推荐在金融、制造等需要严格权限控制的中大型企业中使用其模块化设计使得扩展新业务单元的平均开发周期可缩短至3人日。