一、简介
ruoyi-vue-pro 是一款基于 SpringBoot2.x 全家桶实现、Vue、Element UI 的后台管理系统模板,提供模板功能和CRUD代码生成,并且支持多租户系统、多数据源系统,可浏览器缓存、工作流、十强排行榜、代码生成等常用开发功能。
在本章节中,我们将介绍该系统的基本架构和运行环境。
二、系统架构
本系统的架构基于传统的前后端分离架构模式,采用以下技术栈:
- 前端采用 Vue + Element + Axios + Webpack;
- 后端采用 SpringBoot2.x + MyBatis-Plus + Shiro + Swagger-UI + Log4j2。
三、运行环境
运行该项目需要满足以下环境:
- JDK8+
- Maven 3.0+
- MySQL 5.5+
- Node.js 10+
四、项目结构
本系统的项目结构如下:
ruoyi-vue-pro/ ├── ruoyi-admin/ 后台管理模块 ├── ruoyi-common/ 客户端、服务端公共模块 ├── ruoyi-framework/ 框架核心模块 ├── ruoyi-generator/ java代码自动生成模块 ├── ruoyi-quartz/ 定时任务模块 ├── ruoyi-system/ 后台管理业务模块 ├── ruoyi-tools/ 系统工具模块 └── src/ Vue前端代码
五、代码示例
1. Mybatis-Plus 更改系统默认表名确定方法
在项目中使用Mybatis-Plus的时候,默认情况下表名和实体类名必须一一对应,否则-会出现”无法找到该实体”的错误。在系统多数据源的时候,这种情况更加明显。
/** * 代码生成前缀配置,表名以sys_开头才生成代码 */ strategy.setTablePrefix(new String[] { "sys_" }); /** *根据数据库表获取对应实体类 */ @Override public String tableToJava(String tableName) { if (tableName.startsWith("sys_")) { return upperTableName2Camel(tableName.replaceFirst("sys_", "")); } else if (tableName.startsWith("gen_")) { return upperTableName2Camel(tableName.replaceFirst("gen_", "Gen")); } else if (tableName.startsWith("qrtz_")) { return upperTableName2Camel(tableName.replaceFirst("qrtz_", "Qrtz")); } else { return upperTableName2Camel(tableName); } }
2. 自定义异常处理
异常处理是Web应用开发中非常重要的一环,当系统出现异常时,我们需要有一个统一的异常处理机制。在本项目中,我们通过继承DefaultHandlerExceptionResolver,并重写它的resolveException()方法实现异常处理。
@RestControllerAdvice public class GlobalExceptionHandler extends DefaultHandlerExceptionResolver { @Autowired private MessageSource messageSource; /** * 处理业务异常 */ @ExceptionHandler(BusinessException.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) public R businessException(BusinessException e) { String message = messageSource.getMessage(e.getMessage(), null, LocaleContextHolder.getLocale()); return R.error(message); } /** * 处理未知异常 */ @Override protected ResponseEntity
3. 多租户系统实现
本系统支持多租户,在开发过程中每个公司可以使用一个数据库,将每个公司的相关数据存放在各自的数据库中。我们在引入Mybatis-Plus后,通过继承MybatisSqlInterceptor实现多租户的切换。
@Configuration @MapperScan("com.ruoyi.system.mapper") public class MybatisPlusConfig { @Autowired private RuoYiConfig ruoyiConfig; /** * 多租户方案之一:schema模式 */ @Bean public MybatisSqlInterceptor mybatisSqlInterceptor() { return new MybatisSqlInterceptor() { @Override public void prepare(SqlMappedStatement mappedStatement, Object parameter) { if (SecurityUtils.getMultiTenantId() != null) { final String tenantId = SecurityUtils.getMultiTenantId(); if (StringUtils.isNotBlank(tenantId)) { String originalSql = mappedStatement.getSql(); StringBuilder sqlBuilder = new StringBuilder("SET SCHEMA '") .append(tenantId.toLowerCase()) .append("';"); sqlBuilder.append(originalSql); setPreparedSql(originalSql); setTargetSql(sqlBuilder.toString()); } } } }; } /** * 多租户方案之二:动态表名 */ @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); interceptor.addInnerInterceptor(new DynamicTableNameInnerInterceptor()); return interceptor; } }
4. Vue + Element UI 实现图标操作
Vue + Element UI 可以通过依赖 fontawesome 实现图标操作。在这里我们可以选择几种方式来实现图标的引用:
- 引用CDN上面的fontawesome图标库
- 下载fontawesome文件到本地,然后引用本地文件
- 使用vue-awesome作为插件,安装这个插件,就可以很方便地在vue中使用fontawesome图标库的各种图标了。
npm install --save @fortawesome/fontawesome-svg-core npm install --save @fortawesome/free-solid-svg-icons npm install --save @fortawesome/vue-fontawesome
import Vue from 'vue' import { library } from '@fortawesome/fontawesome-svg-core' import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome' import { faUser } from '@fortawesome/free-solid-svg-icons' // 通过library方法引入想要使用的图标 library.add(faUser) Vue.component('font-awesome-icon', FontAwesomeIcon)
5. Swagger-UI 自动生成API文档
Swagger-UI 可以根据我们代码中的注解自动生成 API 文档。在本项目中,我们可以通过以下配置实现:
/** * swagger配置 */ @Configuration @EnableSwagger2 public class SwaggerConfig { /** * 注入系统基础配置 */ @Autowired private RuoYiConfig ruoyiConfig; @Bean public Docket createRestApi() { // 添加全局头部信息 ParameterBuilder parameterBuilder = new ParameterBuilder(); List parameters = new ArrayList(); parameterBuilder.name("Authorization") .description("令牌") .modelRef(new ModelRef("string")) .parameterType("header") .required(false).build(); parameters.add(parameterBuilder.build()); // API文档基本信息配置 return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.withClassAnnotation(Api.class)) .paths(PathSelectors.any()) .build() .globalOperationParameters(parameters) .securityContexts(Collections.singletonList(securityContext())) .securitySchemes(Collections.singletonList(securityScheme())); } /** * API文档基本信息配置 */ public ApiInfo apiInfo() { return new ApiInfoBuilder() .title("若依系统接口文档") .description("若依管理系统后台接口文档") .contact(new Contact(ruoyiConfig.getName(), null, null)) .version("版本号:" + ruoyiConfig.getVersion()) .build(); } /** * 通过Swagger解决token问题 */ public SecurityScheme securityScheme() { return new ApiKey("Token", "token", "header"); } /** * 通过Swagger解决token问题 */ private SecurityContext securityContext() { return SecurityContext.builder() .securityReferences(Arrays.asList(new SecurityReference("Token", new AuthorizationScope[]{new AuthorizationScope("global", "")}))) .build(); } }
六、总结
本文主要介绍了ruoyi-vue-pro的基本架构和运行环境、项目结构、以及多个方面的代码示例。通过学习以上内容,我们可以更好地理解和使用该系统,从而提高我们的开发效率和协同工作能力。
原创文章,作者:小蓝,如若转载,请注明出处:https://www.506064.com/n/242720.html